Forum: FPGA, VHDL & Co. Reset und Lock des DCM Cores


von Hans-Werner (Gast)


Lesenswert?

Ich habe einen DCM Core erzeugt. Das Problem ist nun das Resetten des 
DCM Cores und das Warten auf das Locked-Signal.
Der DCM Core soll aus dem 50 MHz Takt des Spartan 3 AN Starter Kits 
einén 300 MHz Takt erzeugen. Habe das durch Simulation nachgeprüft.
Bei der Synthese erhalte ich die unten in den VHDL-Text eingefügten 
Fehlermeldungen. Es soll eine VGA-Ausgabe mit 1024x768 Pixeln erfolgen. 
Hierfür benötige ich einen 75 MHz Pixeltakt. Ziel ist die Nachbildung 
des mit dem Board mitgelieferten Fraktal Programmes in höherer Auflösung 
und in Farbe. Für die noch einzufügende Berechnung der Pixel habe ich 
einen 300 MHz Takt erzeugt, den ich für die Ausgabe auf 75 MHz 
runterteile.
Unten habe ich nur die für die Ausgabe verantwortliche Entity 
aufgeführt.
Es soll die Ausgabe mit 1024x768 Pixeln getestet werden.


1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity squares is
6
  port
7
  (
8
    clock : in std_logic; -- 50 MHz Clock
9
    rgb : out std_logic_vector(11 downto 0);
10
    hsync        : out std_logic;
11
      vsync        : out std_logic
12
  );
13
end squares;
14
15
architecture squares_rtl of squares is
16
17
  -- Liefert den 75 MHz Pixelclock für 1024x768 Pixel durch
18
  -- Teilung eines mittels DCM_Core erzeugten 300 MHz Clocks
19
  -- Der 300 MHz Clock soll für Pixelberechnungen genutzt werden
20
   component Clock75MHzEntity
21
  port
22
  (
23
    clock       : in std_logic;    -- 50 MHz
24
    reset       : in std_logic;
25
    locked      : out std_logic;
26
    ibufg_out   : out std_logic;
27
    Clock75MHz  : out std_logic
28
  );
29
  end component Clock75MHzEntity;
30
31
  -- Steuert die VGA Ausgabe
32
  component vga_controller
33
  port(
34
     enable        : in  std_logic;
35
     clock        : in   std_logic;
36
       hsync        : out std_logic;
37
       vsync        : out std_logic;
38
     hcount        : out std_logic_vector(10 downto 0);
39
     vcount        : out std_logic_vector(9 downto 0);
40
     blank         : out std_logic
41
     );
42
  end component vga_controller;
43
  
44
  signal clock75MHz : std_logic;
45
  signal reset : std_logic;
46
  signal locked : std_logic;
47
  signal ibufg_out : std_logic;
48
  
49
  signal red_out, green_out, blue_out : std_logic_vector(3 downto 0);
50
  signal hcount : std_logic_vector(10 downto 0); 
51
  signal vcount : std_logic_vector(9 downto 0);
52
  signal blank : std_logic;   
53
  signal enable_vga_controller : std_logic;
54
  type states is (init, work);
55
  signal state : states;
56
begin
57
58
  label1 : clock75MhzEntity
59
  port map
60
  (    
61
    clock => clock,
62
    reset => reset,
63
    locked => locked,
64
    -- Was fange ich mit ibufg_out an ? 
65
    -- Wozu ist das Signal gut ?
66
    ibufg_out => ibufg_out,
67
    Clock75mhz => clock75MHz
68
  );
69
  
70
   
71
  label2 : vga_controller
72
  port map
73
  (
74
    enable => enable_vga_controller,
75
    clock => clock75mhz,
76
    hsync => hsync,
77
    vsync => vsync,
78
    hcount => hcount,
79
    vcount => vcount,
80
    blank => blank
81
  );
82
83
-- Dieser Prozess verursacht folgende Fehler
84
-- Mapping all equations...
85
-- ERROR:Xst:2035 - Port <clock> has illegal connections. This port is connected to an input buffer and other components.
86
-- Input Buffer:
87
--   Port <I> of node <label1/Inst_DCM300MHzClock/CLKIN_IBUFG_INST> (IBUFG) in unit <squares>
88
-- Other Components:
89
--   Port <C> of node <state_0> (FDE) in unit <squares>
90
--   Port <C> of node <reset> (FDR) in unit <squares>
91
--   Port <C> of node <enable_vga_controller> (FDE) in unit <squares>
92
93
  -- Soll kurz den DCM Core resetten und auf das locked-Signal warten
94
   process (clock)
95
  begin
96
    if rising_edge(clock)
97
    then
98
      case state is
99
        -- Reset the DCM Core
100
        when init => reset <= '1';
101
                 state <= work;
102
        when work => reset <= '0';
103
                -- DCM Core has locked
104
                 if locked = '1'
105
                 then
106
                  enable_vga_controller <= '1';
107
                 else
108
                  enable_vga_controller <= '0';
109
                 end if;
110
      end case;
111
    end if;
112
  end process;
113
114
   -- Falls der DCM Core noch nicht eingelockt hat, können irgendwelche Glitches entstehen
115
  -- In diesem Fall erfolgt noch keine Ausgabe, da der VGAController nicht enabled ist
116
  -- Eine simple Farbausgabe
117
  process (Clock75MHz)
118
  begin
119
    if rising_edge(Clock75MHz)
120
    then
121
      rgb <= red_out & green_out & blue_out;
122
      if blank = '0'
123
      then
124
        for i in 0 to 3 loop
125
            red_out(i) <= hcount(3) and vcount(3);
126
            green_out(i) <= hcount(4) and vcount(4);
127
            blue_out(i) <= hcount(5) and vcount(5);
128
          end loop;
129
       else
130
        for i in 0 to 3 loop
131
          red_out(i) <= '0';
132
          green_out(i) <= '0';
133
          blue_out(i) <= '0';
134
        end loop;
135
       end if;
136
    end if;     
137
  end process;
138
  
139
  
140
end architecture squares_rtl;

von bko (Gast)


Lesenswert?

Aus der Fehlremeldung gehr hervor das die DCM 
Netzliste"clock75MhzEntity"
schon einen "IBUFG" im Takteingang "clock" enthält.
Weil du den Eingang "clock" dann noch im einem Prozess
benutzt muss die XIlinx Synthese noch einen "IBUFG"
in dieses Netz einfügen.

Der Router (par) kann aber nicht zwei IBUFS auf einen
Pin legen !

Aber in deinem VHDL_Code steht schon die richtige
Frage zur Lösung dieses Problems:
ich zitiere: "-- Was fange ich mit ibufg_out an ?
                -- Wozu ist das Signal gut ?"
1
  (...)
2
 -- Soll kurz den DCM Core resetten und auf das locked-Signal warten
3
   process (clock)   <<<--- nimm hier doch mal das "ibufg_out"
4
  begin                      
5
    if rising_edge(clock) <<-- und auch hierda 
6
    then
7
  (...)

von Matthias G. (mgottke)


Lesenswert?

>
1
> entity squares is
2
>   port
3
>   (
4
>     clock : in std_logic; -- 50 MHz Clock
5
>     :
6
>   );
7
> end squares;
8
>
9
>   label1 : clock75MhzEntity
10
>   port map
11
>   (
12
>     :
13
>     -- Was fange ich mit ibufg_out an ?
14
>     -- Wozu ist das Signal gut ?
15
>     ibufg_out => ibufg_out,
16
>     Clock75mhz => clock75MHz
17
>   );

> -- ERROR:Xst:2035 - Port <clock> has illegal connections. This port is
> connected to an input buffer and other components.
> -- Input Buffer:
> --   Port <I> of node <label1/Inst_DCM300MHzClock/CLKIN_IBUFG_INST>
> (IBUFG) in unit <squares>

Als Du Deinen Core "clock75MhzEntity" generiert hast, da hast Du 
ausgewählt, dass ein ibufg (das ist der Port-Eingangsbuffer der das 
Eingangssignal auf eine interne Clock-Leitung legt) im DCM enthalten 
sein soll. Das funtioniert soweit gut, wenn Du das eingehende 
Clocksignal der Entity nur an den generierten DCM legst ohne es noch 
irgendwo zu verwenden.
In Deinem Fall hat er nämlich einen Eingangsbuffer (vermutlich auch 
einen ibug) generiert, der an den Prozess der Reseterzeugung geleitet 
wird. Jetzt will er auf das interne Signal nochmal einen Eingangsbuffer 
routen, denn so stehts im DMC-Core drinn. Das geht aber nicht.

Du hat nun folgende zwei Möglichkeiten: Du generierst den DCM-Core ohne 
den ibufg, dann verschwindet auch das ibufg_out, oder Du führst den 
clock nur an die DCM und kannst deine 50MHz am ibufg_out (das ist dann 
nämlich der Ausgang den Eingangsbuffers) an den Reset-Prozess routen. Im 
RTL-Schaltplan ist das gut zu sehen, wenn Du bis dahin kommst. Die 
Simulation funktioniert deshalb, da ein ibufg nur das Eingangssignal 1:1 
weiter gibt. Die Simulation weiß ja nicht von dem physischen Aufbau der 
Buffer an den Ports.

Bei letzterer Möglichkeit könnte Dein Code so aussehen:
1
entity squares is
2
  port
3
  (
4
    clock : in std_logic; -- 50 MHz Clock
5
    :
6
  );
7
end squares;
8
:
9
  label1 : clock75MhzEntity
10
  port map
11
  (
12
    clock => clock,
13
      :
14
    ibufg_out => clock50MHz,
15
    Clock75mhz => clock75MHz
16
  );
17
:
18
  -- Soll kurz den DCM Core resetten und auf das locked-Signal warten
19
   process (clock50MHz)
20
  begin
21
    if rising_edge(clock50MHz)
Das Signal clock50MHz ist dabei nicht vom Reset oder Funktion der DCM 
abhängig.

Viel Erfolg
Matthias

PS: Ups, sehe gerade ein anderer war schon schneller mit der gleichen 
Antwort.

von Hans-Werner (Gast)


Lesenswert?

Hallo bko

Nach deiner vorgeschlagengen Änderung erhalte ich folgendes:

WARNING:Route - CLK Net:ibufg_out is being routed on general routing 
resources. If you are trying to use local clocking
   techniques, evaluate the placement of the clock's source and loads to 
ensure it meets the guidelines for local
   clocking. Otherwise, consider placing this clock on a dedicated clock 
routing resource. For more information on clock
   routing resources, see the target architecture's user guide.

Einfach nicht beachten, oder ?

von Hans-Werner (Gast)


Lesenswert?

Hallo Matthias

Als Du Deinen Core "clock75MhzEntity" generiert hast, da hast Du
ausgewählt, dass ein ibufg (das ist der Port-Eingangsbuffer der das
Eingangssignal auf eine interne Clock-Leitung legt) im DCM enthalten
sein soll.

Wann und wo habe ich das ausgewählt ?
Welches Menü, welcher Parameter, welcher Wert ?

Du hat nun folgende zwei Möglichkeiten: Du generierst den DCM-Core ohne
den ibufg, dann verschwindet auch das ibufg_out, oder Du führst den
clock nur an die DCM und kannst deine 50MHz am ibufg_out (das ist dann
nämlich der Ausgang den Eingangsbuffers) an den Reset-Prozess routen.

Wie generiere ich den DCM-Core ohne den ibufg ?
Habe es schon versucht, finde keine passende Einstellung.
Der DCM Core für die 300 MHz ist in die clock75MHzEntity eingebunden, da 
momentan die 300 MHz nur für die Generierung der 75MHz verwendet werden. 
Die 300MHz werden (momentan) noch nicht benutzt. Der clock_ibufg_out 
wird vom DCM Core weiter nach "oben" gereicht.
Wenn ich das richtig verstehe soll ich den "normalen" 50 MHz Takts des 
Boards nur an den Eingang des DCM Cores legen. Der ibufg_out liefert 
dann die 50 MHz für die restlichen Prozesse. Der DCM Core hat also nur 
einen Fan In von 1.
Verstehe nicht warum es dann funktionieren soll wenn ich den ibufg_out 
weglasse. Dann kann ich beliebig viele Prozesse an den 50MHz Clock legen 
?

von Matthias G. (mgottke)


Lesenswert?

Hallo Hans-Werner

> Wann und wo habe ich das ausgewählt ?
> Welches Menü, welcher Parameter, welcher Wert ?

Das obige habe ich aus meiner Erinnerung geschrieben, da ich das gleich 
Problem mal vor so ca. einem Jahr hatte. Dort habe ich das Problem am 
RTL-Schaltplan erkannt. Ich habe gerade mal den coregen angeschmissen. 
Wenn ich das noch recht weis ist das der Parameter "CLKIN Source". Dort 
musst Du "Internal" verwenden.
Die Angabe bezieht sich auf die "Single DCM Version 9.204i"

Viel Erfolg
Matthias

von Gustl B. (-gb-)


Lesenswert?

Vielen Dank! Ich hatte auch den Fehler:

ERROR:Xst:2035 - Port <clock> has illegal connections. This port is 
connected to an input buffer and other components.

-gb-

von Ralf (Gast)


Lesenswert?


von Ralf (Gast)


Lesenswert?


von Duke Scarring (Gast)


Lesenswert?

Ralf schrieb:
> Richtig Resetten:
Ich verwende statt diesem komischen SRL16 sowas:
1
    signal reset_shreg   : std_ulogic_vector(3 downto 0) := (others => '1');
2
    signal reset         : std_ulogic := '1';
3
4
    ...
5
6
    reset_generator_p: process
7
    begin
8
        wait until rising_edge( clk);
9
        reset_shreg <= reset_shreg(reset_shreg'left-1 downto 0) & '0';
10
        reset       <= reset_shreg(reset_shreg'left);
11
        if async_reset_pin = '1' then
12
            reset_shreg <= (others => '1');
13
        end if;
14
    end process;

Ralf schrieb:
> und noch was:
Kannst Du da evtl. noch ein paar Quellen mit angeben?
Es gab da m.E. mal was von Peter Alfke (Xilinx)...

Duke

von Sigi (Gast)


Lesenswert?

@Duke Scarring,
>   ...
>   reset <= reset_shreg(reset_shreg'left);
>   ...

warum <reset> im Prozess und nicht Ausserhalb,
so hast du ein Takt Verzögerung und zusätzlich ein FF;
Ausserhalb aber nicht.

von Duke Scarring (Gast)


Lesenswert?

Sigi schrieb:
> warum <reset> im Prozess und nicht Ausserhalb,
> so hast du ein Takt Verzögerung und zusätzlich ein FF;
> Ausserhalb aber nicht.
Das ist richtig.
Aber auf einen Takt früher oder später kommt es beim Reset nicht an. Ich 
habe schon mal ein MIG-Design gesehen, in dem das Reset-Shift_Register 
30 Bits lang war. Durch ein entsprechendes Fanout-Constraint wurde das 
Register dann zu einem Baum vergrößert. Wichtig ist ja (wenn man 
überhaupt einen Reset braucht), daß der überall gleichzeitg losgelassen 
wird.

Duke

von Manuel U. (muml)


Lesenswert?

Wäre es allgemein nicht sinnvoller den einsynchronisierten externen 
Reset nur auf die DCMs zu legen und dann aus den kombinierten 
Lock-Signalen den eigentlichen globalen Reset abzuleiten (natürlich auch 
wieder einsynchronisiert). So könnte man sich Enable-Signale für 
einzelne Module sparen (bezgl. der Vermeidung von Spikes) und nur den 
globalen Reset verwenden.
So habe ich das in einem Referenzdesign von Inrevium gesehen.

Gruß, Manuel

von Sigi (Gast)


Lesenswert?

@Manuel U.,

>Wäre es allgemein nicht sinnvoller den einsynchronisierten externen
>Reset nur auf die DCMs zu legen und dann aus den kombinierten
>Lock-Signalen den eigentlichen globalen Reset abzuleiten ...

so einfach ist es leider nicht. Sind Deine Komponenten von einer
stabilen/best. Clk abhängig, dann ist das locked-Signal eher als
Enable zu empfehlen (sonst laufen Deine Komponenten ja schon vor
einem Locked-Reset an und produzieren Müll).

Zum Locked: Je nach Familie ist Locked synchron zum Clkout etc.
Muss auch berücksichtigt werden. Da selten resettet wird, kann
man aber auch Glück haben :))

von Manuel U. (muml)


Lesenswert?

> [...] Sind Deine Komponenten von einer
> stabilen/best. Clk abhängig, dann ist das locked-Signal eher als
> Enable zu empfehlen (sonst laufen Deine Komponenten ja schon vor
> einem Locked-Reset an und produzieren Müll).

Hi Sigi, da wären meine Komponenten aber doch noch im Reset-Zustand. Sie 
würden erst anlaufen, wenn der aus dem Locked-Signal abgeleitete Reset 
die Komponenten freigibt (und dann ist ja der Clock bereits 
stabil/locked).
Oder gibt es Fälle, in denen Komponenten nicht mehr im Reset-Zustand 
sein sollen, aber noch auf eine DCM warten müssen?

Grüße, Manuel

von Sigi (Gast)


Lesenswert?

>.., da wären meine Komponenten aber doch noch im Reset-Zustand. Sie
>würden erst anlaufen, wenn der aus dem Locked-Signal abgeleitete Reset
>die Komponenten freigibt (und dann ist ja der Clock bereits
>stabil/locked).

Grob betrachtet hast du natürlich recht, ein Problem kann aber z.B.
dann auftreten, wenn im laufenden Betrieb ein Reset an die DCM
geschickt wird. Das Locked-Signal (uU nicht zu den Clk-Signalen
synchron) muss erst einsynchronisiert werden und kann damit zu
Verzögerungen führen, d.h. einzelne Komponenten laufen weiter etc.
... ist iA nicht so einfach zu Beantworten, wurde aber schon das
ein oder andere Mal im Xilinx-Forum thematisiert.

von Martin K. (mkmannheim) Benutzerseite


Lesenswert?

Ich würde sagen, dann muss jeder domain, die das locked verarbeitet 
zusätzlich auch noch den eigentlichen Reset mitnehmen, vorodern und 
ausweren.

Das Problem ist ja weniger der beginnde Reset, sondern der endende!

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.