Diskrepanz zwischen der statischen Timing-Analyse nach Place-and-Route und den ISIM-Simulationsergebnissen

Überblick

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.

Zeiten

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_2ist das Signal aus dem Timing-Bericht. SP_valueist 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_2bis 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.

Frage

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.

Weitere Informationen

Das vollständige Projekt (VHDL-Dateien, XISE-Projekt) ist auf bitbucket verfügbar .

Lassen Sie mich wissen, wenn ich einige wichtige Daten in meiner Frage übersehen habe. Dies sind komplizierte Werkzeuge und ich werde nicht so tun, als ob ich alle (oder sogar die meisten!) Aspekte verstehe.
Warum zeigt bus3 an UUUUUUUU? Ist dies die erste Anweisung, die Sie ausführen, oder gibt es etwas anderes, Udas die Ausbreitung von a verursacht? Ich bin mir nicht sicher, wie STA damit umgeht U, und das könnte Teil Ihres Problems sein.
Es ist die erste eigentliche Anweisung, die wir ausführen. Nach dem Reset-Impuls (nicht gezeigt) führe ich drei Nops (alles mit drei Zuständen) aus, um sicherzustellen, dass die Auswirkungen des Resets abgeklungen sind, und dann führe ich diese Anweisung aus (um den Stapelzeiger zu initialisieren). Das UUUUUUUU auf bus3 ist das Ergebnis der Durchführung der ALU-Operation 0 (und, glaube ich) an zwei ZZZZZZZZ-Eingängen.
Übrigens sind die in der Grafik gezeigten Timings typisch für alle Register-> Bus1-> Bus3-> Registerzyklen. Dies gilt auch, wenn keine UUUUUUUUs in Sicht sind. Ich habe diese Anweisung nur ausgewählt, weil sie als der langsamste Pfad in der STA auftaucht.
Es sieht so aus, als würden Sie den Timing-Bericht richtig lesen, sodass er (höchstwahrscheinlich) darauf beschränkt ist, dass Ihr STA-Setup nicht Ihren Betriebsbedingungen entspricht. Beispielsweise kann eine standardmäßige STA-Annahme sein, dass alle Eingaben bei der ansteigenden Taktflanke stabil (als 1 oder 0 definiert) sind. Gibt es eine Rückkopplungsschleife, die nur angezeigt wird, wenn einige Busse Zoder sind U?
Sind Sie übrigens wirklich sicher, dass Sie Tri-State brauchen? Das allein kann viel Kummer in STA verursachen.
Ach, ich verstehe. Sie meinen, der Decoder muss die Signale direkt in HDL zuweisen ("if sel=x"1" then bus1<=register1; end if;") und sich bei der Synthese um die Drähte kümmern, anstatt explizit mit "falscher Verkabelung" herumzuspielen auf „Z“ stellen. Es kam mir nie in den Sinn. Ich gucke mal.
Meiner Erfahrung nach sollten interne Z's wie ein Hammer behandelt werden - in bestimmten Fällen nützlich, aber keine Wunderlösung oder sogar eine bevorzugte Lösung.
Ich habe meinen Code so geändert, dass er niemals ein Z ausgibt (ich ging so weit, alle Z-Zeichen in meinen Quelldateien zu untersuchen). Dies hatte einen kleinen Einfluss auf die STA-Ausgabe (3 ns Schlupf statt 6 ns) und einen großen Einfluss auf die Simulationsausgabe. Ich kann es jetzt mit einem 10-ns-Takt ausführen und die Ausgabe ist konsistent. Anscheinend hast du das Problem gelöst! Wenn Sie es als Antwort hinzufügen, werde ich es akzeptieren.

Antworten (1)

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 1oder bedeutet 0). UUUUUUUUDas on sieht sofort bus3sehr verdächtig aus und ist ein mögliches Problem bei der Initialisierung. In Logiksimulationen Ubedeutet dies, dass die Zeile entweder ein 1oder 0ist, 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 bus1der 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.

Ich habe meinen Code so geändert, dass er niemals ein Z ausgibt (ich ging so weit, alle Z-Zeichen in meinen Quelldateien zu untersuchen). Dies hatte einen kleinen Einfluss auf die STA-Ausgabe (3 ns Schlupf statt 6 ns) und einen großen Einfluss auf die Simulationsausgabe. Ich kann es jetzt mit einem 10-ns-Takt ausführen und die Ausgabe ist konsistent.