Ich implementiere eine einfache CPU im Harvard-Stil mit Xilinx ISE Version 14.1. Ich verwende Einstellungen, die mit einem Digilent Nexys3-Board kompatibel sind, aber vorerst wird das gesamte Projekt nur in Simulation durchgeführt.
Ich habe den folgenden Eintrag in meiner UCF-Datei, der die Position (Pin) der Uhr auf der Nexys3-Karte zusammen mit einer Periodenbeschränkung von 100 MHz angibt. Dies bedeutet eine Periode von 10 ns.
Net "clk" LOC=V10 | IOSTANDARD=LVCMOS33;
Net "clk" TNM_NET = sys_clk_pin;
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 100000 kHz;
Ich takte die gesamte synchrone Logik mit der positiven Flanke dieser Uhr.
Die statische Timing-Analyse nach Place-and-Route zeigt, dass alles in Ordnung ist:
Timing constraint: TS_sys_clk_pin = PERIOD TIMEGRP "sys_clk_pin" 100 MHz HIGH
50%;
For more information, see Period Analysis in the Timing Closure User Guide (UG612).
12987 paths analyzed, 961 endpoints analyzed, 0 failing endpoints
0 timing errors detected. (0 setup errors, 0 hold errors, 0 component switching limit errors)
Minimum period is 4.003ns.
Die Mindestperiode liegt gut innerhalb des Ziels von 10 ns. Der Bericht enthält keine unbeschränkten Pfade.
Der Bericht nennt diesen Pfad dann zuerst. Da das Timing übereinstimmt, nehme ich an, dass es der langsamste Pfad im Design ist (der Pfad mit dem geringsten Durchhang). Es ist der Pfad vom Befehlsregister zum höchsten Bit des Stapelzeigers. Der Pfad (durch die ALU und Bus 3) sieht für mein Design vernünftig aus, wenn das Register mit einem sofortigen Wert geladen wird. Der Push/Pop-Pfad nimmt einen anderen Pfad.
Slack (setup path): 5.997ns (requirement - (data path - clock path skew + uncertainty))
Source: CONTROL/IR_15_2 (FF)
Destination: SP/VALUE_31 (FF)
Requirement: 10.000ns
Data Path Delay: 3.951ns (Levels of Logic = 9)
Clock Path Skew: -0.017ns (0.252 - 0.269)
Source Clock: clk_BUFGP rising at 0.000ns
Destination Clock: clk_BUFGP rising at 10.000ns
Clock Uncertainty: 0.035ns
Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE
Total System Jitter (TSJ): 0.070ns
Total Input Jitter (TIJ): 0.000ns
Discrete Jitter (DJ): 0.000ns
Phase Error (PE): 0.000ns
Maximum Data Path at Slow Process Corner: CONTROL/IR_15_2 to SP/VALUE_31
Location Delay type Delay(ns) Physical Resource
Logical Resource(s)
------------------------------------------------- -------------------
SLICE_X13Y30.BQ Tcko 0.391 CONTROL/IR_15_3
CONTROL/IR_15_2
SLICE_X5Y31.D3 net (fanout=12) 0.847 CONTROL/IR_15_2
SLICE_X5Y31.D Tilo 0.259 RAM/read_address<1>
ALU1/Mmux_RR11241
SLICE_X14Y24.B3 net (fanout=4) 1.283 bus3_1_OBUF
SLICE_X14Y24.COUT Topcyb 0.380 SP/VALUE<3>
SP/Mcount_VALUE_lut<1>
SP/Mcount_VALUE_cy<3>
SLICE_X14Y25.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<3>
SLICE_X14Y25.COUT Tbyp 0.076 SP/VALUE<7>
SP/Mcount_VALUE_cy<7>
SLICE_X14Y26.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<7>
SLICE_X14Y26.COUT Tbyp 0.076 SP/VALUE<11>
SP/Mcount_VALUE_cy<11>
SLICE_X14Y27.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<11>
SLICE_X14Y27.COUT Tbyp 0.076 SP/VALUE<15>
SP/Mcount_VALUE_cy<15>
SLICE_X14Y28.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<15>
SLICE_X14Y28.COUT Tbyp 0.076 SP/VALUE<19>
SP/Mcount_VALUE_cy<19>
SLICE_X14Y29.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<19>
SLICE_X14Y29.COUT Tbyp 0.076 SP/VALUE<23>
SP/Mcount_VALUE_cy<23>
SLICE_X14Y30.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<23>
SLICE_X14Y30.COUT Tbyp 0.076 SP/VALUE<27>
SP/Mcount_VALUE_cy<27>
SLICE_X14Y31.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<27>
SLICE_X14Y31.CLK Tcinck 0.314 SP/VALUE<31>
SP/Mcount_VALUE_xor<31>
SP/VALUE_31
------------------------------------------------- ---------------------------
Total 3.951ns (1.800ns logic, 2.151ns route)
(45.6% logic, 54.4% route)
Mit diesem Wissen bewaffnet führe ich eine Post-Place-and-Route-Simulation mit einer Taktperiode von 10 ns durch und denke, dass alles in Ordnung sein wird. Dies ist jedoch nicht der Fall. Die Signale schwingen sich nicht rechtzeitig zur nächsten Taktflanke ein und alles ist durcheinander. Das Entspannen der Uhr auf 50 ns (20 MHz) lässt viel Zeit, damit sich alles einpendelt.
Bei 425 ns erhalten wir den Taktimpuls, der den Beginn des Zyklus signalisiert, in dem wir die Anweisung ausführen werden SP <- 0xFFFFFFFF
. IR_15_2
ist das Signal aus dem Timing-Bericht. SP_value
ist ein Register, also nimmt es nur den Wert an, der ihm bei der nächsten steigenden Flanke präsentiert wird. SP wird von bus3 geladen, also verwenden wir das als Proxy.
In der Grafik sehen wir, dass es ungefähr 3 ns dauert, IR_15_2
bis es überhaupt behauptet wird. Dann dauert es über 10ns länger, bis das Signal von Bus1 übernommen wird. Bei 451 ns, ganze 26 ns später, ist das Signal auf bus3 verfügbar und wir können darüber nachdenken, SP damit zu laden.
Statisches Timing sagt mir, dass der längste Register-zu-Register-Pfad im Design etwa 4 ns dauern sollte, während die Simulation zeigt, dass die Signale etwa 26 ns brauchen, um sich einzuschwingen. Was geht hier vor sich? Findet die statische Timing-Analyse nicht alle relevanten Pfade? Habe ich den Simulator falsch verwendet/konfiguriert? Habe ich die statische Timing-Analyse falsch gelesen?
Ich kann das Design mit 20 MHz ausführen, dies ist kein Geschwindigkeitswettbewerb. Ich habe einfach das Gefühl, dass mir etwas Wichtiges fehlt.
Das vollständige Projekt (VHDL-Dateien, XISE-Projekt) ist auf bitbucket verfügbar .
Beim Durchsehen Ihres Timing-Berichts gibt es nichts, was auf ein potenzielles Problem hindeutet. Da Sie ein Problem haben, bedeutet dies, dass die Szenarien, die von der statischen Zeitanalyse (STA) überprüft werden, nicht die tatsächliche Nutzung Ihrer Schaltung abdecken.
Ohne ernsthafte Einrichtung von STA gehen einige gängige Annahmen davon aus, dass alle Eingaben gültig sind, wenn die Uhr ansteigt, und dass alle Zustände bekannt sind (was eine Logik 1
oder bedeutet 0
). UUUUUUUU
Das on sieht sofort bus3
sehr verdächtig aus und ist ein mögliches Problem bei der Initialisierung. In Logiksimulationen U
bedeutet dies, dass die Zeile entweder ein 1
oder 0
ist, aber ein Register, das sie ansteuert, nicht richtig initialisiert wurde. Dies könnte dazu führen, dass der Simulator seltsame Antworten gibt, bis alle Register geladen oder zurückgesetzt sind. Dieses Problem manifestiert sich jedoch in späteren Zyklen, nachdem alle Register initialisiert wurden.
Das andere mögliche Problem ist bus1
der Start in einem Zustand mit hoher Impedanz ( ZZZZZZZZ
). In Anbetracht der Tatsache, dass in der Zeitanalyse normalerweise nicht von Tristate ausgegangen wird, ist dies die wahrscheinlichste Quelle der Zeitabweichung. Tri-State-Bedingungen müssen sorgfältig in Ihr STA-Tool codiert werden, damit sie berücksichtigt werden können. Dies kann eine sehr schwierige Aufgabe sein und ist fehleranfällig (falsche Programmierung, fehlende Fälle usw.). Ich glaube, dass die Programmierung in Tri-State-Verzögerungen Ihnen höchstwahrscheinlich ein genaues STA-Ergebnis liefern würde, das Ihrer Simulation entsprechen sollte.
Allerdings ist Tri-State normalerweise eine schlechte Wahl für die On-Chip-Kommunikation sowohl für ASICs als auch für FPGAs. Diese Mehrdeutigkeit der STA-Zuverlässigkeit, das Potenzial für Buskonflikte und die Ungewissheit der Laufwerksstärkeanforderungen machen es wahrscheinlicher, dass Tri-State Probleme verursacht, als sie zu beheben. Die sicherere Methode besteht darin, einen Multiplexer zu verwenden, um auszuwählen, welche Quelle mit dem Bus "spricht", oder das Design anders zu partitionieren. Ich würde Tri-State nur dann verwenden, wenn ich weiß, dass es mehr Probleme löst, als es verursachen kann.
drxzcl
W5VO
UUUUUUUU
? Ist dies die erste Anweisung, die Sie ausführen, oder gibt es etwas anderes,U
das die Ausbreitung von a verursacht? Ich bin mir nicht sicher, wie STA damit umgehtU
, und das könnte Teil Ihres Problems sein.drxzcl
drxzcl
W5VO
Z
oder sindU
?W5VO
drxzcl
W5VO
Z
's wie ein Hammer behandelt werden - in bestimmten Fällen nützlich, aber keine Wunderlösung oder sogar eine bevorzugte Lösung.drxzcl