Forum: FPGA, VHDL & Co. Clock Enable, wie macht man's richtig?


von Matthias K. (kruessi80)



Lesenswert?

Hi,

habe folgendes Problem, bei dem ich gerne Rat von den Profi's hätte:

Ein Modul, welches TEST_CLOCK_ENABLE heißt,
soll als Füllstandsberechnung des BRAMS dienen.
Ich habe in meinem System einen Takt mit 100MHz (CLK_100MHz) aus dem
ich mit einem Zähler alle 4 Takte einen Enable Puls (ECLK_25MHz)
erzeuge, welcher dann über das ganze System verbreitet wird.

Im Anhang ist hierzu die Implementierung "Test_Clock_Enable_0.vhd".
Dazu die Netzliste "Test_Clock_Enable_0.png".

Wie man erkennen kann, wird dem Zähler ein "neues"
kombinatorisches Clock-Enable Signal generiert.
Ich möchte jedoch haben, dass das Register ausschließlich
mit eclk_25MHz übernommen wird. Dies ist der Fall, wenn
ich das attribute keep auf "bram_fill_level_nw" setze.
(siehe "Test_Clock_Enable_1.vhd", "Test_Clock_Enable_1.png")
Hierbei meldet nun die Xilinx (10) - Synthese:
1
[...]
2
WARNING:Xst:387 - The KEEP property attached to the net <bram_fill_level_nw<15>> may hinder timing optimization.
3
   You may achieve better results by removing this property
4
[...]

Diese lässt sich noch unterdrücken wenn ich das attribute "TIG" auf 
"bram_fill_level_nw" setze.
(siehe "Test_Clock_Enable_2.vhd")

------
Warum das Ganze:
Soweit ich feststellen konnte, gibt es in der 
Post-Place/&-Route-Simulation Setup-/Hold-Probleme,
wenn der Füllstand nicht, wie die restliche Logik, mit dem ECLK-25MHz 
getriggert wird.

------
Frage:

* Kann man der ISE irgendwie beibringen das Clock-Enable Signal wirklich 
zu benutzen ohne die Attribute?
* Gibt es eine einfachere / bessere Art dies zu implementieren?

Danke im voraus für Eure Ratschläge.
Matthias

[update]
Sorry, ein Fehler hat sich eingeschlichen:
In "Test_Clock_Enable_0.vhd" müssen die beiden Zeilen auskommentiert 
werden:
1
   attribute keep : string;
2
   attribute keep of bram_fill_level_nw : signal is "true";

von Matthias K. (kruessi80)


Lesenswert?

Hi,

der vorherige Beitrag war als Beispiel gedacht. Vermutlich zu komplex.
Vielleicht könnt ihr hierzu was sagen:
Ich habe ein Signal das je nach Eingangszustand togglen soll.
Wenn ich das unten Beispiel simuliere, bekomme ich in der
Post-Place&Route Simulation für das Toggle-Signal einen
Setup-Fehler. Was läuft hier falsch?

Wenn ich mir die Xilinx Schematic ansehe,
wird wie im obrigen Beispiel, das Clock_Enable-Signal
des toggle_s-Flipflops aus einer Kombinatorik von ECLK_25MHz und
weiteren Signalen gebildet.
Die anderen Signale A, B, C... sind jedoch
direkt mit ECLK_25MHz enabled. Daher ist aus Sicht der Simulation
die Setup-Verletzung auch berechtigt.

Soweit ich informiert bin empfiehlt ja Xilinx möglichst
mit einem Clock und als Teiler mit Clock_Enable Signalen
zu arbeiten. Ist es in dem Fall vielleicht doch besser
mit einer DCM 25MHz zu generieren und dies zu verwenden?

Liegt das Problem möglicherweise an der etwas älteren ISE 10?
1
process (clk_100MHz)
2
begin
3
    if rising_edge(clk_100MHz) then
4
        if (rst_s='1') then
5
            toggle_s <= '0';
6
        elsif (eclk_25MHz) then
7
            if (Enable = '1') then
8
                if (a ='1' and b='1') then
9
                    if (toggle_s ='1') then
10
                        toggle_s <= '0';
11
                    else
12
                        toggle_s <= '1';
13
                    end if;
14
                elsif (c='1') then
15
                    -- toggle_s bleibt unverändert
16
                elsif (d='1') then
17
                    -- toggle_s bleibt unverändert
18
                elsif (e='1') then
19
                    if (toggle_s ='1') then
20
                        toggle_s <= '0';
21
                    else
22
                        toggle_s <= '1';
23
                    end if;
24
                end if;
25
            end if;
26
        end if;
27
    end if;
28
end process;

Veilleicht liegt das Problem auch am ECLK_25MHz Signal.
Ich habe folgenden Aufbau:
/TOP_MODUL/CLOCK_GENERIERUNG <- ECLK_25MHz wird aus 100MHz erzeugt.
/TOP_MODUL/MODUL1/ ECLK_25MHz wird verwendet.
/TOP_MODUL/MODUL2/ ECLK_25MHz wird verwendet.
/TOP_MODUL/MODUL3/ ECLK_25MHz wird verwendet.
TOP_MODUL.../ ECLK_25MHz wird verwendet.

Bei den Haupt-Modulen auf erster Ebene habe ich
das Attribut KEEP_HIERARCHY eingeschaltet.

Somit hängt ein Großteil der Schaltung direkt an diesem 
Clock-enable-Signal.
Macht es Sinn dieses Clock-Enable-Signal für jedes Modul nochmals wie 
nachfolgend zu synchronisieren?
Oder macht man es sogar so, dass man dieses Signal in jedem Modul neu 
generiert?
1
eclk_25MHz_s <= eclk_25MHz when rising_edge(100MHz);

Viele Grüße
Matthias

von Duke Scarring (Gast)


Lesenswert?

Den generierten Schematics würde ich nicht 100% vertrauen. Ich hab schon 
erlebt, das da Leitungen gefehlt haben.

Bei einem vollständig synchronen Design, sollte die Statische Timing 
Analyse völlig ausreichen. Mir kommt auch die Verwendung der Attribute 
hier komisch vor.

Hast Du Deine 100 MHz im .ucf-File richtig angegeben?

Vielleicht ist auch Dein reset das Problem?! Ich würde den nur an einer 
Stelle einsynchronisieren...

Duke

von Matthias K. (kruessi80)


Lesenswert?

Duke Scarring schrieb:
> Den generierten Schematics würde ich nicht 100% vertrauen. Ich hab schon
> erlebt, das da Leitungen gefehlt haben.

ok. Das hätte ich nicht erwartet.

> Bei einem vollständig synchronen Design, sollte die Statische Timing
> Analyse völlig ausreichen. Mir kommt auch die Verwendung der Attribute
> hier komisch vor.

Die Statische Timing-Analyse ist völlig in Ordnung.
Die Simulation (behav, post-synthese) sind auch i.O..
Problematisch wird es erst bei den Simulationen
ab post-map, bzw. bei post-place& route.

>
> Hast Du Deine 100 MHz im .ucf-File richtig angegeben?
Denke schon.
Die 100MHz werden mit einer DCM aus dem 20MHz Eingangssignal generiert.
Das Constraint ist dann im UCF nicht nötig und wird von der ISE gemacht.
Müsste dann so aussehen:
1
NET "CR/DCM2/DCM2_100MHz_w" TNM_NET = "CLK_100MHz";
2
TIMESPEC "TS_CR_DCM2_DCM2_100MHz_w" = PERIOD "CLK_100MHz" 10 ns HIGH 50 %;

Habe im UCF das Eclk_25Mhz als Multicycle-clock angegeben.
Dies wird im Timing-Teil der Reports richtig erkannt.
1
NET "CR/ECLK_25MHz" TNM_NET = FFS MY_25MHz_GRP;
2
TIMESPEC TS_Multicycle_25MHz = FROM "MY_25MHz_GRP" TO "MY_25MHz_GRP" TS_CR_DCM2_DCM2_100MHz_w * 4;

Auszug aus dem Timing-Report:
1
Derived Constraint Report
2
Derived Constraints for TS_CLK_20MHz
3
+-------------------------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
4
|                               |   Period    |       Actual Period       |      Timing Errors        |      Paths Analyzed       |
5
|           Constraint          | Requirement |-------------+-------------|-------------+-------------|-------------+-------------|
6
|                               |             |   Direct    | Derivative  |   Direct    | Derivative  |   Direct    | Derivative  |
7
+-------------------------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
8
|TS_CLK_20MHz                   |     50.000ns|          N/A|     48.625ns|            0|            0|            0|       133314|
9
| TS_CR_DCM1_100MHz_w           |     10.000ns|          N/A|      9.725ns|            0|            0|            0|       133314|
10
|  TS_CR_DCM2_DCM2_100MHz_w     |     10.000ns|      7.003ns|      3.155ns|            0|            0|          172|       133030|
11
|   TS_Multicycle_25MHz         |     40.000ns|     12.618ns|          N/A|            0|            0|       132198|            0|
12
|   TS_Multicycle_2MHz          |    500.000ns|          N/A|          N/A|            0|            0|            0|            0|
13
|   TS_Multicycle_1MHz          |   1000.000ns|      8.806ns|          N/A|            0|            0|          832|            0|
14
|  TS_CR_DCM2_125MHz_w          |      8.000ns|          N/A|      7.780ns|            0|            0|            0|          112|
15
|   TS_CR_DCM3_DCM3_125MHz_w    |      8.000ns|      7.780ns|          N/A|            0|            0|          112|            0|
16
| TS_CR_DCM1_DCM1_20MHz_w       |     50.000ns|          N/A|          N/A|            0|            0|            0|            0|
17
+-------------------------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
18
19
All constraints were met.

> Vielleicht ist auch Dein reset das Problem?! Ich würde den nur an einer
> Stelle einsynchronisieren...

Möglicherweise, ja.
Andererseits hatte ich, soweit ich mich entsinnen kann,
mit nur einem Reset, bei Simulationen Probleme mit der
Synchronität bzw. mit resultierenden Setup-/Hold-Fehlern...

Standardmäßig ist ja in der ISE das KEEP_HIERARCHY attribut 
ausgeschaltet und das ganze Design wird dann, nach der Synthese flach 
mit nur einer Entity. Für die Simulation ist es angenehmer dies entweder 
komplett oder teilweise einzuschalten. Ich habe beschlossen dies nur für 
meine oben liegenden Module einzuschalten, damit die Module, welche ich 
mit dem
Xilinx Core-Generator generiert habe, sich "einnisten" können.
Vielleicht schafft dies aber insgesammt mehr Probleme als die
resultuierenden Vorteile in der Simulationsumgebung.

Macht dies noch jemand so?

Grüße,
Matthias

von Matthias K. (kruessi80)


Lesenswert?

Hey,

ist es evt. entgegen der Xilinx-Empfehlung
"nur einen Takt auf dem gesamten Chip"
sinnvoll die DCM auf 50MHz zu betreiben
und daraus die doppelte und halbe Frequenz
direkt zu benutzen? (So hätte ich auch 100Mhz und 25Mhz).

Vermutlich liegt dann aber das Problem darin,
dass die Takte nicht über die gesamte Chip-Fläche
("in allen Ecken") synchron zueinander
gehalten werden können, oder doch? was meint ihr?

Grüße
Matthias

von Duke Scarring (Gast)


Lesenswert?

Matthias Krüßelin schrieb:
> Vermutlich liegt dann aber das Problem darin,
> dass die Takte nicht über die gesamte Chip-Fläche
> ("in allen Ecken") synchron zueinander
> gehalten werden können, oder doch? was meint ihr?

Genau dafür gibt es doch die "Globalen Netzwerke", erreichbar über die 
BUFG.
Und meines Wissens nach steckt Xilinx da eine ganze Menge Knowhow rein, 
damit der Takt doch "gleichzeitig" an die FFs kommt. Das klappt in 
kleineren FPGAs vermutlich besser, als in Großen.

Aber diese Synchronität sicherzustellen sollte nicht Deine Aufgabe sein. 
Das macht das Tool über die Constraints schon richtig (meiner 
bescheidenen Erfahrung nach).

Duke

von berndl (Gast)


Lesenswert?

Matthias Krüßelin schrieb:
> Denke schon.
> Die 100MHz werden mit einer DCM aus dem 20MHz Eingangssignal generiert.
> Das Constraint ist dann im UCF nicht nötig und wird von der ISE gemacht.
> Müsste dann so aussehen:NET "CR/DCM2/DCM2_100MHz_w" TNM_NET = "CLK_100MHz";
> TIMESPEC "TS_CR_DCM2_DCM2_100MHz_w" = PERIOD "CLK_100MHz" 10 ns HIGH 50 %;

Halt, so nicht! Du gibst im .ucf nicht den internen Takt vor, sondern 
den externen. ISE bzw. die Tools machen dann schon die richtigen Sachen, 
um mit dem internen Takt rechnen zu koennen. Bei mir z.B. im .ucf 
folgendes, mit einer externen 20ns clock und interner 10ns clock nach 
dem DCM:
1
NET "clk" TNM_NET = clk;
2
TIMESPEC TS_clk = PERIOD "clk" 20 ns HIGH 50%;
Damit funktioniert die statische Timing-Analyse wunderbar...

von Matthias K. (kruessi80)


Lesenswert?

berndl schrieb:
> Matthias Krüßelin schrieb:
>> Denke schon.
>> Die 100MHz werden mit einer DCM aus dem 20MHz Eingangssignal generiert.
>> Das Constraint ist dann im UCF nicht nötig und wird von der ISE gemacht.
>> Müsste dann so aussehen:NET "CR/DCM2/DCM2_100MHz_w" TNM_NET = "CLK_100MHz";
>> TIMESPEC "TS_CR_DCM2_DCM2_100MHz_w" = PERIOD "CLK_100MHz" 10 ns HIGH 50 %;
>
> Halt, so nicht! Du gibst im .ucf nicht den internen Takt vor, sondern
> den externen. ISE bzw. die Tools machen dann schon die richtigen Sachen,
> um mit dem internen Takt rechnen zu koennen. Bei mir z.B. im .ucf
> folgendes, mit einer externen 20ns clock und interner 10ns clock nach
> dem DCM:NET "clk" TNM_NET = clk;
> TIMESPEC TS_clk = PERIOD "clk" 20 ns HIGH 50%;Damit funktioniert die statische 
Timing-Analyse wunderbar...

Da hast mich wohl missverstanden.
Natürlich habe ich den externen Takt eingetragen.
(In meinem Fall 20MHz = 50 ns)
Ich wollte nur andeuten was Xilinx daraus macht.

Grüße
Matthias

von Duke Scarring (Gast)


Lesenswert?

@Matthias

Was geht und was geht denn jetzt nicht bei Dir:

[ ] funktionale Simulation + STA
[ ] post-synthesis Simulation
[ ] post-translate Simulation
[ ] post-map Simulation
[ ] post-par Simulation
[ ] Design auf der Hardware

Wenn bei mir das erste funktioniert, funktioniert auch der letzte Punkt 
(außer ich habe mal wieder einen seltenen Synthesefehler erwischt).

Duke

von Matthias K. (kruessi80)


Lesenswert?

Duke Scarring schrieb:
> @Matthias
>
> Was geht und was geht denn jetzt nicht bei Dir:
>
> [ ] funktionale Simulation + STA
> [ ] post-synthesis Simulation
> [ ] post-translate Simulation
> [ ] post-map Simulation
> [ ] post-par Simulation
> [ ] Design auf der Hardware
>
> Wenn bei mir das erste funktioniert, funktioniert auch der letzte Punkt
> (außer ich habe mal wieder einen seltenen Synthesefehler erwischt).
>
> Duke

Hi,

[x] funktionale Simulation + STA
[x] post-synthesis Simulation
[-] post-translate Simulation
[x] post-map Simulation
[-] post-par Simulation (mit sdf-typ)
[?] Design auf der Hardware


(x) funktioniert:
(-) geht nicht
(?) Auf der Hardware läufts hat aber teils merkwürdige Effekte.


Grüße
Matthias

PS: das ganze ist auf einem Spartan 3...

von Matthias K. (kruessi80)


Lesenswert?

Hey,

habe gerade die Simulationen nochmals durchgeführt.
Bei der "post-map Simulation" bekomme ich keine Fehler.
Jedoch bekomme ich bei der "post-par Simulation (mit sdf-typ)"
lauter solche Fehler dieser Art:
1
# ** Warning: /X_SFF SETUP  Low VIOLATION ON CE WITH RESPECT TO CLK;
2
#   Expected := 0.602 ns; Observed := 0.443 ns; At : 14164.99 ns
3
#    Time: 14164990 ps  Iteration: 3  Instance: /pia_tb/dut/pia_inst/tx/fa/fcs_r_2
4
# ** Warning: /X_SFF SETUP  Low VIOLATION ON CE WITH RESPECT TO CLK;
5
#   Expected := 0.602 ns; Observed := 0.37 ns; At : 14164.99 ns
6
#    Time: 14164990 ps  Iteration: 3  Instance: /pia_tb/dut/pia_inst/tx/fa/fcs_r_19
7
# ** Warning: /X_SFF SETUP  Low VIOLATION ON CE WITH RESPECT TO CLK;
8
#   Expected := 0.602 ns; Observed := 0.37 ns; At : 14164.99 ns
9
#    Time: 14164990 ps  Iteration: 3  Instance: /pia_tb/dut/pia_inst/tx/fa/fcs_r_0
10
# ** Warning: /X_SFF SETUP  Low VIOLATION ON CE WITH RESPECT TO CLK;
11
#   Expected := 0.602 ns; Observed := 0.37 ns; At : 14164.99 ns
12
#    Time: 14164990 ps  Iteration: 3  Instance: /pia_tb/dut/pia_inst/tx/fa/fcs_r_1
13
# ** Warning: /X_SFF SETUP  Low VIOLATION ON CE WITH RESPECT TO CLK;
14
#   Expected := 0.602 ns; Observed := 0.443 ns; At : 14164.991 ns
15
#    Time: 14164991 ps  Iteration: 3  Instance: /pia_tb/dut/pia_inst/tx/fa/fcs_r_3
16
# ** Warning: /X_SFF SETUP  Low VIOLATION ON CE WITH RESPECT TO CLK;
17
#   Expected := 0.602 ns; Observed := 0.475 ns; At : 14165.003 ns

Dies an all denen DFF, bei denen das Clock-Enable nicht direkt
von ECLK_25MHz sondern über eine Kombinatorik hergestellt wurde.

..ist echt zum verzweifeln...


Ist es möglich, dass man das Clock-Enable nur dann verwenden sollte,
wenn die Frequenzen wesentlich niederiger sind?

Gruß
Matthias

von Matthias K. (kruessi80)


Lesenswert?

Hey,

da ich nun vor der Entscheidung stehe,
entweder mehrere Clocks zu verwenden oder
die Statemachines so zu verändern dass wirklich
CE auf jedem DFF richtig ist, wollte ich noch kurz
nachfragen wie Ihr das in eueren Designs gelöst habt???

Ich kann's nicht verstehen, dass ich der einzige sein
soll, der solch massive Probleme hat!

Matthias

von Jan M. (mueschel)


Lesenswert?

Hallo Matthias,
ich denke dass dein Problem mit ziemlicher Sicherheit nicht unmittelbar 
mit dem Clockenable zusammenhängt. CE kann man in jedem Design bei jeder 
beliebigen Frequenz verwenden, ohne dass es prinzipielle Probleme gibt.
Schau dir z.B. das an, was die Synthese aus vielen Codestücken macht, 
die kein explizites CE enthalten - in vielen Fällen wird trotzdem der 
CE-Eingang eines Flipflops benutzt um anderweitig Ressourcen zu sparen.

Ich vermute das Problem eher in der Erzeugung von ECLK25 - hier scheint 
mir eine größere Verzögerung nach der 100 MHz Taktflanke zu sein bis 
ECLK25 valide ist. Kommt dann noch durch Optimierung kombinatorische 
Logik dazu wie von dir oben gezeigt, ist die Signallaufzeit zu lang und 
es kommt zu deinem Problem.

Versuche doch mal, direkt nach der Erzeugung von ECLK25 noch ein 
Flipflop einzufügen, das kann dein Timing entscheidend verbessern.

Außerdem: Wie wird ECLK25 und CLK100 im Chip verteilt? Über ein globales 
Taktnetz, ein lokales Taktnetz oder über normales Routing?

von Matthias K. (kruessi80)


Lesenswert?

Hi,

Jan M. schrieb:
> Hallo Matthias,
> ich denke dass dein Problem mit ziemlicher Sicherheit nicht unmittelbar
> mit dem Clockenable zusammenhängt. CE kann man in jedem Design bei jeder
> beliebigen Frequenz verwenden, ohne dass es prinzipielle Probleme gibt.

Hört sich gut an.

> Schau dir z.B. das an, was die Synthese aus vielen Codestücken macht,
> die kein explizites CE enthalten - in vielen Fällen wird trotzdem der
> CE-Eingang eines Flipflops benutzt um anderweitig Ressourcen zu sparen.

Ja, das habe ich auch schon gesehen und ist mir auch bewusst.

>
> Ich vermute das Problem eher in der Erzeugung von ECLK25 - hier scheint
> mir eine größere Verzögerung nach der 100 MHz Taktflanke zu sein bis
> ECLK25 valide ist. Kommt dann noch durch Optimierung kombinatorische
> Logik dazu wie von dir oben gezeigt, ist die Signallaufzeit zu lang und
> es kommt zu deinem Problem.

Nachfolgend ist die Erzeugung des ECLK_25MHz-Signals.
1
entity CLOCK_RESET_ECLK is
2
   port (RST        : in  std_logic;
3
         CLK_100MHz : in  std_logic;
4
         ECLK_25MHz : out std_logic
5
         );              
6
end CLOCK_RESET_ECLK;
7
8
architecture behav of CLOCK_RESET_ECLK is
9
   constant CLK_25MHz_VALUE_3_bc : std_logic_vector(1 downto 0) := "11";
10
   constant CLK_25MHz_VALUE_0_bc : std_logic_vector(1 downto 0) := "00";
11
begin
12
13
   CLK_25MHz_COUNTER : process (RST, CLK_100MHz)
14
   begin
15
      if (RST = '1') then
16
         CLK_25MHz_COUNT_s <= (others => '0');
17
      elsif rising_edge (CLK_100MHz) then
18
         if (CLK_25MHz_COUNT_s = CLK_25MHz_VALUE_0_bc) then
19
            CLK_25MHz_COUNT_s <= CLK_25MHz_VALUE_3_bc;
20
         else
21
            CLK_25MHz_COUNT_s <= CLK_25MHz_COUNT_s - '1';
22
         end if;
23
      end if;
24
   end process;
25
26
CLK_EN_25MHz_GEN : process (RST, CLK_100MHz)
27
begin
28
   if (RST = '1') then
29
      ECLK_25MHz_s <= '0';
30
   elsif rising_edge (CLK_100MHz) then
31
      if (CLK_25MHz_COUNT_s = CLK_25MHz_VALUE_0_bc) then
32
         ECLK_25MHz_s <= '1';
33
      else
34
         ECLK_25MHz_s <= '0';
35
      end if;
36
   end if;
37
end process;
38
   ECLK_25MHz <= ECLK_25MHz_s;
39
end behav;

>
> Versuche doch mal, direkt nach der Erzeugung von ECLK25 noch ein
> Flipflop einzufügen, das kann dein Timing entscheidend verbessern.

Ok. Werde ich versuchen.

>
> Außerdem: Wie wird ECLK25 und CLK100 im Chip verteilt? Über ein globales
> Taktnetz, ein lokales Taktnetz oder über normales Routing?

Das ECLK_25MHz habe ich dann einfach in alle Module,
die dies benötigen, "weiterverdrahtet" (vermutlich normals Routing).

CLK_100MHz greife ich aus der DCM ab und leite es auf ein BUFG.
Den Ausgang des BUFG verwende ich dann als Takt.

Danke im voraus,
Matthias

von Matthias K. (kruessi80)


Lesenswert?

>>
>> Versuche doch mal, direkt nach der Erzeugung von ECLK25 noch ein
>> Flipflop einzufügen, das kann dein Timing entscheidend verbessern.
>
> Ok. Werde ich versuchen.
>

Hat die Lage leider nicht verbessert!

Bin gerade dabei das Signal (ECLK_25MHz) über ein BUFG
(globales Netz) dem System zu geben. Bin sehr gespannt.
Eine Fehlermeldung des MAP-Reports ist hierbei schon:
1
WARNING:LIT:175 - Clock buffer is designated to drive clock loads. BUFGMUX
2
   symbol "CR/ECLK/physical_group_ECLK_25MHz/ECLK_BUFG_INST" (output
3
   signal=ECLK_25MHz_o_OBUF) has a mix of clock and non-clock loads. Some of the
4
   non-clock loads are (maximum of 5 listed):
5
   Pin CE of Tx/FA/dataValid_r
6
   Pin CE of Tx/FA/data_sr0_0
7
   Pin CE of Tx/FA/data_sr0_1
8
   Pin CE of Tx/FA/data_sr0_2
9
   Pin CE of Tx/FA/data_sr0_3

Grüße, Matthias

von Duke Scarring (Gast)


Lesenswert?

Das ist eine Warnung und die bezieht sich auf den Ausgang Deines 
Clock-(BUFG)-Buffers. Und zwar treibst Du damit diverse CE (Clock 
Enables) statt die C(lock)-Eingänge von FFs.

Duke

von Jan M. (mueschel)


Lesenswert?

Matthias Krüßelin schrieb:
>>>
>>> Versuche doch mal, direkt nach der Erzeugung von ECLK25 noch ein
>>> Flipflop einzufügen, das kann dein Timing entscheidend verbessern.
>>
>> Ok. Werde ich versuchen.
>>
>
> Hat die Lage leider nicht verbessert!

Gut - bei der Beschreibung von ECLK25 befindet sich ja schon ein FF 
direkt am Ende, da kann das zusätzliche FF nicht viel machen - außer die 
Laufzeit des Signals quer durch den FPGA.

Der BUFG wird hier nicht viel bringen. Wenn ich mich richtig erinnere, 
dann sind die globalen Netzwerke ausschließlich an die Takteingänge der 
FF angeschlossen und können nicht ohne weiteres andere Eingänge der 
Slices treiben.

Die constraints, die du oben zitiert hast sahen soweit auch passend aus. 
Ich denke dass dein Problem eigentlich von einer ganz anderen Stelle 
kommt - wahrscheinlich irgendein winziger Fehler den man leicht 
übersieht. Dafür werden wir aber wohl das komplette Projekt und die 
place'n'route und timing reports anschauen müssen.

von Matthias K. (kruessi80)


Lesenswert?

> Gut - bei der Beschreibung von ECLK25 befindet sich ja schon ein FF
> direkt am Ende, da kann das zusätzliche FF nicht viel machen - außer die
> Laufzeit des Signals quer durch den FPGA.

Ja, stimmt.

> Der BUFG wird hier nicht viel bringen. Wenn ich mich richtig erinnere,
> dann sind die globalen Netzwerke ausschließlich an die Takteingänge der
> FF angeschlossen und können nicht ohne weiteres andere Eingänge der
> Slices treiben.

Schade eigentlich. Wäre ja echt toll.

> Die constraints, die du oben zitiert hast sahen soweit auch passend aus.
Gut.

> Ich denke dass dein Problem eigentlich von einer ganz anderen Stelle
> kommt - wahrscheinlich irgendein winziger Fehler den man leicht
> übersieht. Dafür werden wir aber wohl das komplette Projekt und die
> place'n'route und timing reports anschauen müssen.

Ich vermute dass ich das Projekt nicht hochladen darf. 
(Firmengeheimnis...)
Allein mit den Reports werdet Ihr wahrscheinlich nichts anfangen können,
oder doch?
Werde diese nochmals durchsehen. Vielleicht findet sich noch
ein Hinweis.

Gruß, Matthias

von Matthias K. (kruessi80)


Lesenswert?

Hi,

Ihr werdet's nicht glauben, aber jetzt läuft die PAR-Simulation! :-)

Habe das ECLK_25MHz und den synchronen Reset
in jedem Modul einsynchronisiert (s.u.)
und musste noch ein paar wenige, große State-Machines nach oben
geannten Verfahren in einen synchronen und einen kombinatorischen 
Prozess
aufteilen.
1
   attribute keep : string;
2
   attribute keep of rst_s, eclk_25MHz_s : signal is "TRUE";
3
begin
4
   rst_s        <= rst_100MHz when rising_edge(clk_100MHz);
5
   eclk_25MHz_s <= eclk_25MHz when rising_edge(clk_100MHz);

Nachteil ist nun, dass ich im ucf-File für jedes Modul einen
separaten multi-cycle-contraint erstellen muss. Naja, unschön,
aber damit kann ich leben.

Danke nochmals für die unterstützende Hilfe!
Matthias

von Anguel S. (anguel)


Lesenswert?

Ich würde diese ganzen Attribute nicht verwenden, wer weiß ob die die 
Tools nicht durcheinanderbringen. Kannst Du mit DCMs direkt arbeiten? 
Dann wird machen die Tools alles automatisch.

von Stefan W. (wswbln)


Lesenswert?

...das Ganze klingt aber immer noch ein wenig nebulös.

Führst Du den eclk_CLK25MHz_s denn ausschließlich direkt auf die div. CE 
Eingänge, oder kommt da stellnweise noch Kombinatorik ins Spiel? Sind 
die Eingangssignale der Kombinatorik (auch die, die an den Dateneingang 
der FFs gehen) synchronisiert? Kannst Du die Kombinatorik von den 
CE-Eingängen ggf. an die Dateneingänge verlegen?

von Matthias K. (kruessi80)


Lesenswert?

Hey,

habe gerade folgendes mit dem Floor-Planer festgestellt:
Ich habe das Signal "Eclk_25MHz" im Top-Modul für die Testbench
nach draußen "verdrahtet".
1
eclk_25MHz_o <= eclk_25MHz;

Hierdurch ist natürlich ein OBUF entstanden.
Jedoch wird schaltungsintern nicht das "eclk_25MHz"-Signal
sondern das "eclk_25MHz_o"-Signal als Clock-Enable
der ganzen internen Register verwendet, was ja schlecht ist,
da dieses Signal total durch den OBUF verzögert wird.

Ergo habe ich das nun erst mal händisch korrigiert:
1
   ECLK_25MHz_out : OBUF
2
   port map (O => ECLK_25MHz_o, 
3
             I => ECLK_25MHz);

Mal schauen wie sich das ganze auswirkt.
Werde euch berichten.
gruß, Matthias

von Matthias K. (kruessi80)


Angehängte Dateien:

Lesenswert?

Hi,


habe ein Test-System gebaut (ISE 10) und angehängt:

Dabei werden wie gehabt, 100MHz-System-Takt genommen
und daraus 25MHz generiert.
1
Top-Modul:
2
/TEST_CLOCK_ENABLE/ (Test_clock_enable.vhd)
3
4
Clock-Enable und Reset Erzeugung:
5
/TEST_CLOCK_ENABLE/RST_ECLK/ (rst_eclk.vhd)
6
7
132-Bit breiter Füllstand:
8
/TEST_CLOCK_ENABLE/FILL_LEVEL_0_INST/ (fill_level.vhd)
9
/TEST_CLOCK_ENABLE/FILL_LEVEL_1_INST/ (fill_level.vhd)
10
/TEST_CLOCK_ENABLE/FILL_LEVEL_2_INST/ (fill_level.vhd)
11
/TEST_CLOCK_ENABLE/FILL_LEVEL_3_INST/ (fill_level.vhd)
12
13
UCF-File mit Constraints:
14
(test_clock_enable.ucf)

Mit diesen riesigen Addierern, wird sichergestellt,
dass wirklich mehr als 10ns benötigt werden.
Mit den mehrfachen Instanzen wird auch das ECLK_25MHz-Signal
mehrfach erzeugt. (Aus "View/Edit Routed Design (FPGA-Editor)"
ersichtlich).

Komisch ist nun folgendes:
Im Design ist das ECLK_25MHz Signal über OBUF nach draußen geführt.
Das "Post-Place & Route Static Timing" ist NICHT ok
und bemängelt die Reset-Pfade.

Wenn ich das ECLK_25MHz NICHT nach außen führe,
ist das Post-Place & Route Static Timing ok.

Wie kann man sich das erklären?

Grüße
Matthias

von Matthias K. (kruessi80)


Angehängte Dateien:

Lesenswert?

Hi,

habe im Xilinx-Forum folgendes erfahren:

> I didn't quite follow all of your logic,
> but here's a trick that helps to replicate a clock enable:
> 1)  Assuming that your enable signal runs at a constant rate, say every
>  4th cycle of the high-speed clock, then you only ned to synchronize it
>  to some external edge at the "start of time" and from then on it will
>  happen every 4th clock cycle.
> 2) Once you are no longer near the "start of time",
>  then a signal that is delayed by
>  high-speed clocks from the original enable signal will always be the
>  same as the original signal.
>
> So all you need to do is add a 4-stage shift register to the enable
> signal and use its output as the global clock enable.
> This becomes very easy to replicate,
> because even if the last of the four flip-flops needs to be
> replicated hundreds of times, then the 3rd stage could also be
> easily replicated.  So the tools have something to build a
> tree from and it should work as long as you enable register
> duplication (and shut off equivalent register removal.

> Also you don't need a KEEP attribute on the shifted output,
> because even though it is equivalent to the original clock enable
> signal after a few clock cycles, it is
> not equivalent at time zero, so the tools cannot throw it away.

So habe ich ein Schieberegister im Top-modul erzeugt und mir
die ECLK_25Mhz der verschiedenen Register in der Post-Place-& Route
Simulation angesehen (siehe Bild).


Wie man hier erkennt, ist das Eingangssignal
von "piat_tb/dut/pia_inst/stat/tsmat/eclk_*"
bereits so spät, sodas dieses erst nach der Taktflanke
am Register anliegt.
So wie es aussieht, wird in jedem Sub-modul das Signal aufgesplittet
und verzögert, obwohl dies im VHDL-Code direkt durchgeroutet ist!

Hat noch jemand einen Lösungsvorschlag?

Gruß,
Matthias

von Matthias K. (kruessi80)



Lesenswert?

Hi,

habe nun KEEP_HIERACHY="NO" auf die Module "stat", "tsmat" und 
submodules of "tsmat" angewendet.

Habe das Signal "eclk_25Mhz_sr" im Top-module zu "sr_eclk_25Mhz" 
umbenannt.

Jetzt bekomme ich 14 Instanzen von eclk_25MHz_sr_3* und das Timing 
scheint ok zu sein.

Kann es kaum fassen, dass dieses "KEEP_HIERARCHY" so das Timing 
verändert!

Grüße
Matthias

von Anguel S. (anguel)


Lesenswert?

Matthias Krüßelin schrieb:
> Kann es kaum fassen, dass dieses "KEEP_HIERARCHY" so das Timing
> verändert!

Mir ist auch folgende Situation aufgefallen:
Ich habe ein Design und da kommt ein Timing nicht ganz hin. Ich füge 
dann ein Signal hinzu, das ich an einen externen Pin ausführe und für 
Debuggen nutzen möchte. Anscheinend schiebt Xilinx dann aufgrund des 
neuen Signals bisschen was hin und her, und plötzlich kommt das Timing 
doch hin :) Anscheinend hängt alles sehr stark von den Positionen ab und 
da spielt wohl der Zufall auch eine gewisse Rolle.

von Matthias K. (kruessi80)


Lesenswert?

Noch ein kleiner Nachtrag:

Habe gelesen, dass bei KEEP_HIERARCHY="SOFT" die Synthese
schneller als bei KEEP_HIERARCHY="NO" sein soll.

Bei mir wird dieses Attribut nun nur noch über die Xilinx-Einstellung
verändert - habe in allen Modulen jenes entfernt.

Synthesis "Rerun all": (von Begin, bis grünes Häkchen).
KEEP_HIERARCHY="NO"   -  5 min, 19 sec.
KEEP_HIERARCHY="SOFT" -  7 min,  5 sec.

Soviel dazu...

Grüße
Matthias

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.