Forum: FPGA, VHDL & Co. Erklärung dcm s3e


von Clemens M. (panko)


Lesenswert?

hi,

Ich habe mir über das Karnevalswochenende vorgenommen mich des obigen 
Themas anzunehmen und da sind natürlich Fragen aufgetaucht.
Nachdem ich erst mal ziemlich dröge die xilinx pdf gewälzt habe, ist mir 
das zu bunt geworden und ich habe mir 'hands on' zu Herzen genommen. Mit 
folgendem code habe ich die 50 MHz vom Nexys 2 verdoppelt. Mit dem 
coregenerator eine single dcm ausgewählt und den CLK_FB als intern 
zurückgekoppelt eingestellt.
Ein nächster Schritt wird sicher sein, den Eingangstakt zu teilen oder 
einen krummen Takt zu bauen. Aber dafür muss ich das einfach besser 
verstehen.
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity dcm_top is
5
    Port ( clk : in  STD_LOGIC;
6
           led : out  STD_LOGIC);
7
end dcm_top;
8
9
architecture Behavioral of dcm_top is
10
signal led_s : std_logic;
11
signal count_s : integer range 0 to 50000000/1 := 0;
12
signal clk_s : std_logic;
13
signal dcm_lock : std_logic;
14
component dcm
15
   port ( CLKIN_IN        : in    std_logic; 
16
          CLKIN_IBUFG_OUT : out   std_logic; 
17
          CLK2X_OUT       : out   std_logic; 
18
          LOCKED_OUT      : out   std_logic);
19
end component;
20
21
22
begin
23
  led <= led_s;
24
  --clk_s <= clk; --das dann an die dcm
25
  instantiate_dcm : dcm port map(
26
    CLKIN_IN => clk,   
27
      CLKIN_IBUFG_OUT => open,
28
      CLK2X_OUT => clk_s,
29
      LOCKED_OUT => dcm_lock );
30
  
31
  toggle : process begin
32
    wait until rising_edge(clk_s);
33
    if( dcm_lock = '1' ) then
34
      if(count_s < 50000000/1) then
35
        count_s <= count_s + 1;
36
      else
37
        count_s <= 0;
38
        led_s <= not led_s;
39
      end if;
40
    end if; --dcm_lock
41
  end process toggle;
42
43
end Behavioral;

Meine primäre Frage gilt dem Signal CLKIN_IBUFG_OUT, der auf open 
gesetzt sein kann. Kann als Frage, denn wozu zwingt der Coregenerator 
das Signal auf, wenn man es doch offen lässt?
Wie ich es verstanden habe, würde die Sache bei mir so laufen, daß der 
Eingangstakt (bei dem Nexys ja ein global clk Eingang) über einen global 
Buffer Input in den CLK_IN der dcm gelangt. Vom Ausgang dann über einen 
Buffer ins Taktnetzwerk. Die Rückkopplung auf CLK_FB hat die Komponente 
tatsächlich selber gemacht.
Meine Frage also: warum  CLKIN_IBUFG_OUT => open und warum ist CLK_IN 
mit clk zufrieden? Ich beziehe das auf ug331 S.69 wo es mir so scheint, 
als ob eben CLK_IN aus diesem Buffer kommen müsste.
Wäre der Eingangstakt eigentlich zusätzlich zu einer angeschlossenen dcm 
noch als clk im design verfügbar, oder müsste dafür eine zweite dcm 
angeschlossen werden?

EDIT: ich habe den logischen Weg gewählt und es einfach mal probiert - 
"Port <clk> has illegal connections. This port is connected to an input 
buffer and other components." hört sich so an, als ob das tatsächlich 
nicht geht. Macht auch Sinn. Eine zweite dcm an einen Buffer kann ich 
aber vermutlich generieren?

Verworrene Fragen, aber ich hoffe jemand versteht es, mir zu helfen.

Ach und zuletzt: wann müsste man eigentlich von Hand irgendwelche Buffer 
Zuweisungen machen? Das habe ich auf auto gelassen. Auto klingt einfach 
und funktionierend ;-)

von Gustl B. (-gb-)


Lesenswert?

Diese Formatierung von port map, also mit den => Pfeilen sehe ich hier 
öfters und finde sie leicht verwirrend.

Du schreibst:

CLKIN_IN => clk,

Was bewirkt das? Müsste der Pfeil nicht die andere Richtung haben? Es 
wird doch den CLKIN_IN die clk zugewiesen und nicht anders herum?

Ich schreibe port map immer so:

instantiate_dcm : dcm port map(clk,open,clk_s,dcm_lock);

Dabei geht der erste Eintrag, also clk, an den ersten Eintrag der 
component Definition, also hier an CLKIN_IN. Und alle Weiterin der 
Reihenfolge nach.

Oder habe ich einen Denkfehler?

von Duke Scarring (Gast)


Lesenswert?

Clemens M. schrieb:
> Kann als Frage, denn wozu zwingt der Coregenerator
> das Signal auf, wenn man es doch offen lässt?
Der Code, den der Coregenerator generiert, ist nicht immer logisch. 
(Aber fast immer verwirrend ;-)
Vielleicht ist das Signal drin, weil es in einer anderen Konfiguration 
gebraucht wird.

> Wäre der Eingangstakt eigentlich zusätzlich zu einer angeschlossenen dcm
> noch als clk im design verfügbar, oder müsste dafür eine zweite dcm
> angeschlossen werden?
Wenn ich mir UG331 [1], Seite 47, Bild 2-2 "Spartan-3E and Extended 
Spartan-3A Family Internal Quadrant-Based Clock Structure" anschaue, 
eher nicht. Du kannst aber aus einer DCM verschiedene Takte rausholen 
und im Design verwenden.

> Ach und zuletzt: wann müsste man eigentlich von Hand irgendwelche Buffer
> Zuweisungen machen?
Ich instanziiere die DCM immer per Hand. Da kommt ein IBUFG (oder 
IBUFGDS) an den Eingangstakt. Die restlichen Buffer (für DCM-Feedback 
und das interne Design) macht der Synthesizer (zumindest beim Spartan 6) 
automatisch.

Duke

[1] http://www.xilinx.com/support/documentation/user_guides/ug331.pdf

von Duke Scarring (Gast)


Lesenswert?

Gustl Buheitel schrieb:
> Ich schreibe port map immer so:
>
> instantiate_dcm : dcm port map(clk,open,clk_s,dcm_lock);
Genau das vermeide ich wie die Pest.
Das mag zwar bei Code schreiben etwas Tipparbeit sparen, aber man muß 
sich merken, an welcher Position welches Signal steht.
Und die Reihenfolge hab ich längst vergessen, wenn ich nach einer 
gewissen Zeit mal wieder in den Code schauen muss.

Bei der ausführlichen Beschreibung ist die Reihenfolge egal und es passt 
auch noch ein Kommentar an jedes Signal:
1
    dcm_sp_i0: dcm_sp
2
        generic map (
3
            CLKDV_DIVIDE            => 2.0,     -- Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5
4
                                                -- 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0
5
            CLKFX_MULTIPLY          => fx_mul,  -- Can be any integer from 2 to 32
6
            CLKFX_DIVIDE            => fx_div,  -- Can be any integer from 1 to 32
7
            CLKIN_DIVIDE_BY_2       => FALSE,   -- TRUE/FALSE to enable CLKIN divide by two feature
8
            CLKIN_PERIOD            => 20.0,    -- Specify period of input clock
9
            CLKOUT_PHASE_SHIFT      => "NONE",  -- Specify phase shift of "NONE", "FIXED" or "VARIABLE"
10
            CLK_FEEDBACK            => "1X",    -- Specify clock feedback of "NONE", "1X" or "2X"
11
            DESKEW_ADJUST           => "SYSTEM_SYNCHRONOUS", -- "SOURCE_SYNCHRONOUS", "SYSTEM_SYNCHRONOUS" or
12
                                                             -- an integer from 0 to 15
13
            DLL_FREQUENCY_MODE      => "LOW",   -- "HIGH" or "LOW" frequency mode for DLL
14
            DUTY_CYCLE_CORRECTION   => TRUE,    -- Duty cycle correction, TRUE or FALSE
15
            PHASE_SHIFT             =>    0,    -- Amount of fixed phase shift from -255 to 255
16
            STARTUP_WAIT            => TRUE     -- Delay configuration DONE until DCM_SP LOCK, TRUE/FALSE
17
        )
18
        port map (
19
            CLK0        => clk0,             -- 0 degree DCM CLK ouptput
20
            CLK90       => clk90,            -- 90 degree DCM CLK output
21
            CLK180      => clk180,           -- 180 degree DCM CLK output
22
            CLK270      => clk270,           -- 270 degree DCM CLK output
23
            CLK2X       => clk2x,            -- 2X DCM CLK output
24
            CLK2X180    => open,             -- 2X, 180 degree DCM CLK out
25
            CLKDV       => clkdv_int,        -- Divided DCM CLK out (CLKDV_DIVIDE)
26
            CLKFX       => clkfx_int,        -- DCM CLK synthesis out (M/D)
27
            CLKFX180    => open,             -- 180 degree CLK synthesis out
28
            LOCKED      => clk_ready,        -- DCM LOCK status output
29
            PSDONE      => psdone,           -- Dynamic phase adjust done output
30
            STATUS      => dcm_sp_i0_status, -- 8-bit DCM status bits output
31
            CLKFB       => clk0,             -- DCM clock feedback
32
            CLKIN       => clk,              -- Clock input (from IBUFG, BUFG or DCM)
33
            PSCLK       => clk,              -- Dynamic phase adjust clock input
34
            PSEN        => psen,             -- Dynamic phase adjust enable input
35
            PSINCDEC    => psincdec,         -- Dynamic phase adjust increment/decrement
36
            RST         => arst              -- DCM asynchronous reset input
37
        );
38
        psovfl     <= dcm_sp_i0_status(0);
39
        clkdv      <= clkdv_int;
40
        clkfx      <= clkfx_int;
41
        clk50      <= clk0;

> Oder habe ich einen Denkfehler?
In dem Fall: ja :-)

Duke

von Gustl B. (-gb-)


Lesenswert?

Oh ok, Danke! Wieder was gelernt, also wird in der Schreibweise

CLKIN_IN => clk

tatsächlich entgegen der Pfeilrichtung zugewiesen, gut zu wissen.

von Clemens M. (panko)


Lesenswert?

Weiß man denn, an welchem IBUFG der clk ankommt? Das kann vom pin 
unterschiedlich verdrahtet sein?
Ist die obige componente vielleicht da, daß man das nicht wissen muss?
Könnte ich  CLKIN_IN oder CLKIN_IBUFG_OUT aus dem generierten code 
rauswerfen?

von Duke Scarring (Gast)


Lesenswert?

Clemens M. schrieb:
> Weiß man denn, an welchem IBUFG der clk ankommt?
Ja. Weil Du ja sagst, an welchem Pin der Takt anliegt. Wenn der Pin die 
GCLK-Funktion enthält, hängt da dran auch der entsprechende IBUFG.
 sein?

> Könnte ich  CLKIN_IN oder CLKIN_IBUFG_OUT aus dem generierten code
> rauswerfen?
Versuch macht kluch.
Ich denke schon. Der Core-generator erzeugt ja für die DCM-Sachen keine 
Netzlisten, sondern einigermaßen lesbaren VHDL (oder Verliog) Code.

Duke

von Clemens M. (panko)


Lesenswert?

Ich probier mal weiter. War mir nicht klar geworden, daß zu einem pin 
ein fester Buffer gehört. Ich dachte die könnten auch irgendwie geroutet 
werden.

Wenn ich noch irgendwas überhaupt nicht verstehe pushe ich mich noch 
mal.

Danke einstweilen!

von Duke Scarring (Gast)


Lesenswert?

Clemens M. schrieb:
> Ich probier mal weiter. War mir nicht klar geworden, daß zu einem pin
> ein fester Buffer gehört. Ich dachte die könnten auch irgendwie geroutet
> werden.
Prinzipiell ja. Aber für globale Netzwerke (wie den Takt) gibt es 
dedizierte Pins. Und die sollte man auch dafür nutzen.

Duke

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.