Simulation
Logiksimulation
Eine ereignisgesteuerte Simulation der digitalen Teile eines Schaltplans: 74er-Serie-Modelle, Primitive, Stimulation, Assertions, Setup und Hold, VCD-Ausgabe.
Eine ereignisgesteuerte Simulation der digitalen Teile eines Schaltplans, direkt aus dessen Netlist; kein Layout erforderlich. agentee new sim NAME --kind logic (MCP new_item mit kind = "sim" und sim_kind = "logic") schreibt eine Vorlage mit einem Takt, einem Reset und einer taktsynchronen Assertion, die du auf deine Netze umbenennen kannst; --kind fdtd, der Standard, startet stattdessen eine FDTD-Simulation. agentee sim NAME (MCP run_sim) schreibt NAME.result.json und eine VCD-Wellenform NAME.vcd neben die Spezifikation; der Viewer zeichnet eine Spur pro aufgezeichnetem Netz gegen die Zeit.
In der Wellenformansicht zoomt das Mausrad (oder Kneifen, oder Strg und Mausrad) um den Zeiger, ein Ziehen oder seitliches Scrollen verschiebt die Ansicht, ein Doppelklick passt die gesamte Laufzeit an, und ein Klick setzt den Zeitcursor, an den Rand der darunterliegenden Zeile innerhalb weniger Pixel angeheftet. + und - zoomen um den Cursor, die Pfeiltasten verschieben, F oder Home passt an, Escape entfernt den Cursor, und N und P springen den Cursor zum nächsten bzw. vorherigen Marker. Wenn mehr Zeilen als Platz vorhanden sind, scrollen das Mausrad über die Namen, ein Ziehen oder Klick auf den Balken am rechten Rand sowie Page Up und Page Down die Zeilen (top=N in --show startet bei Zeile N). Die Spalte neben den Namen liest jede Zeile am Cursor aus (am Zeiger ohne Cursor, sonst am rechten Rand der Ansicht), und der Hover-Tipp gibt die Zeit vom Cursor an. Netze mit Namen von X[0] bis X[n], oder X0 bis Xn (auch X0_N bis Xn_N), werden zu einer Bus-Zeile zusammengefasst, in Hex dargestellt, MSB zuerst, mit einem Nibble x für unbekannte Bits und z für schwebende; ebenso ein record-Eintrag { name, nets }. Klicke auf einen Bus-Namen, um seine Bits zu öffnen. Die VCD hält dieselben Buses als Vektoren anstelle ihrer Bits: Q0 bis Q3 als $var wire 4 # Q [3:0] $end, Y0_N bis Y7_N als Y_N [7:0] und ein record-Bus mit n Netzen als NAME [n-1:0], MSB zuerst. Marker oben zeigen jede fehlgeschlagene Assertion (rot, zum Zeitpunkt der Prüfung), Zeitverletzung (bernsteinfarben) und Konflikt (violett), mit einem Punkt auf den Zeilen der beteiligten Netze; hovere über einen für seine Meldung, klicke ihn an, um den Cursor dorthin zu setzen. Eine Laufzeit behält ihre ersten 10000 Marker, und der Header gibt an, wenn diese Grenze erreicht wurde. agentee render NAME --show from=300ns,to=900ns,cursor=550ns,open=Q[3:0] zeichnet dieselbe Ansicht ohne Benutzeroberfläche.
name = "counter"
kind = "logic"
schematic = "counter" # default: the only top-level schematic
duration = "2us"
ignore = ["J1", "J2"] # parts with no logic model to leave out
record = ["CLK", "Q3", "Q2", "Q1", "Q0"] # default every net but the rails
# record = ["CLK", { name = "COUNT", nets = ["Q3", "Q2", "Q1", "Q0"] }] # a bus, MSB first
# on_violation = "keep" # default "x": a timing violation makes the flip-flop x
[[stimulus]]
net = "CLK"
clock = { period = "100ns", duty = 0.5, phase = "50ns" }
[[stimulus]]
net = "RST_N"
steps = [["0ns", 0], ["120ns", 1]] # [time, level] in time order; levels 0, 1, "x", "z"
[[stimulus]]
net = "MODE"
constant = 1
[[expect]] # a level at a time
net = "TC"
at = "1600ns"
value = 1
[[expect]] # a bus, MSB first: a number or a string of 0 1 x z and - (any)
nets = ["Y7_N", "Y6_N", "Y5_N", "Y4_N", "Y3_N", "Y2_N", "Y1_N", "Y0_N"]
at = "600ns"
value = "11011111"
[[expect]] # a sequence sampled on clock edges
nets = ["Q3", "Q2", "Q1", "Q0"]
clock = "CLK"
edge = "rising" # or "falling"
from = "0ns" # edges before this are skipped
sequence = [0, 0, 1, 2, 3, "01--"]Ein Takt ist niedrig bis phase, dann hoch für duty von jedem period; ohne Phase startet er hoch bei 0. Ein Stimulus treibt sein Netz als starker Treiber; auf einem Versorgungsnetz ersetzt er die Schiene. Eine at-Prüfung liest das Netz, sobald alles zu diesem Zeitpunkt abgeklungen ist; eine Sequenz liest die Netze kurz vor jeder sauberen Flanke (0 zu 1 oder 1 zu 0) des Takts, sodass ein registrierter Ausgang so gesehen wird, wie er war, als die Flanke kam. Netze werden benannt wie im Schaltplan, und ein Netz, das über eine 0-Ohm-Verbindung mit einem anderen verbunden ist, antwortet auf beide Namen.
Die Netliste wird wie folgt in Zellen umgewandelt:
- Netze mit
style = "power"und Versorgungssymbolen (ein Symbol mitpower = true) sind konstante Quellen: Ein Name mitGND, oder beginnend mitVSS,VEEoder0V, ist 0, jeder andere ist 1 (PWR_FLAGwird übersprungen). - Ein Widerstand (
R) von 0 Ohm, ein Jumper (JP,SJ, Pins 1 und 2) und eine Netztie (NT) verbinden ihre Netze zu einem. Jeder andere Widerstand zwischen einer Schiene und einem Netz ist ein Pull-up oder Pull-down, ein schwacher Treiber des Schienenpegels; zwischen zwei Signalnetzen verbindet er sie; zwischen zwei Schienen wird er weggelassen. - Kondensatoren, Induktivitäten, Perlen, Filter, Dioden, LEDs, Testpunkte, Löcher, Fiduzialmarken und Kristalle (
C,L,FB,FL,D,LED,TP,H,MH,FID,Y,X) werden weggelassen. - Bauteile, deren Wert (oder sonst der Symbolname) eine 74er-Seriennummer enthält, verwenden das eingebaute Modell nach Pinnummer:
74HC00,SN74LVC1G08DBVRundCD74HCT04Estimmen alle überein. Die Bibliothek deckt 00, 01, 02, 03, 04, 05, 06, 07, 08, 10, 11, 14, 20, 21, 27, 32, 74, 86, 125, 126, 132, 138, 157, 161, 163, 164, 244, 245, 573, 574 und 595, die Einzelgatter 1G00, 1G02, 1G04, 1G06, 1G07, 1G08, 1G14, 1G17, 1G32, 1G34, 1G74, 1G79, 1G80, 1G86, 1G125, 1G126 und 1G157, sowie die Doppelgatter 2G00, 2G02, 2G04, 2G08, 2G14, 2G17, 2G32, 2G34, 2G74, 2G86, 2G125 und 2G126 ab. Eine Einheit eines Mehrfach-Symbols, die nicht platziert ist, wird weggelassen; ein platzierter Pin ohne Netz wird als schwebend (z) gelesen. - Die 14 (und 1G14, 2G14) Schmitt-Trigger sind Inverter; die Simulation hat keine langsame analoge Flanke, auf die die Hysterese wirken könnte. Die 573 ist acht
dlatchund die 574 achtdff, jeweils mit dem gemeinsamenOE(Pin 1, aktiv niedrig), das die Ausgänge schweben lässt. Die 245 ist achtxcvr: Bei niedrigemOE(Pin 19) treibt sie B von A, solangeDIR(Pin 1) hoch ist, und A von B, solange es niedrig ist. Die 01, 03 (Quad-NAND), 05, 06, 1G06 (Inverter) und 07, 1G07 (Puffer) sind Open-Drain: Sie ziehen niedrig oder lassen los (z), und ein Pull-up-Widerstand erzeugt die 1. Jede 01 hat das 7402-Pinlayout (Ausgänge an 1, 4, 10, 13, Eingaben danach), gemäß TI SDLS026 (SN7401, SN74LS01) und Renesas REJ03D0532 (HD74HC01); die 03 hat das 7400-Layout, gemäß TI SCLS077 (SN74HC03). - Ein Gatter, dessen Ausgangspins in seinem Symbol alle
open_collectorsind, ist ebenfalls Open-Drain. - Bauteile, deren Wert oder Symbol ein Primitivname ist (
AND,NAND3,OR,NOR,XOR,XNOR,NOT,INV,BUF,TRIBUF,DFF,JKFF,SRLATCH,DLATCH,MUX2), mappen ihre Pins nach Name:D,CLK(auchC,CP,CK),S/SET/PRE,R/RST/CLR,EN,OE,Q,~{Q}; der Ausgang eines Gatters ist seinoutput-Pin (oderY,Q,OUT), und jeder andere Signalpin ist ein Eingang. Ein Überstrich (~{R}), ein nachgestelltes#oder_N, oder eine invertierte Pinform macht den Pin aktiv niedrig. - Jedes andere Bauteil ist ein Fehler, der es benennt, es sei denn, es steht in
ignoreoder hat ein[[parts]]-Modell.
Familientiming, aus den Familienbuchstaben nach 74 (Propagationverzögerung, Setup, Hold sowie Recovery und Removal eines asynchronen Set oder Reset):
| Familie | Verzögerung | Setup | Hold | Recovery | Removal |
|---|---|---|---|---|---|
| HC, HCT | 10 ns | 15 ns | 3 ns | 8 ns | 0 |
| AHC, AHCT, VHC, VHCT | 6 ns | 5 ns | 1 ns | 3,5 ns | 0 |
| AC, ACT | 6 ns | 4 ns | 1 ns | 2,4 ns | 0 |
| LVC | 4 ns | 3 ns | 1 ns | 2 ns | 0 |
| ALVC, LVT, ALVT, AUC, AVC | 4 ns | 2 ns | 1 ns | 2 ns | 0 |
| AUP, LV, LVX | 6 ns | 3 ns | 1 ns | 3 ns | 1 ns |
| LS und einfache 74 | 15 ns | 20 ns | 5 ns | 25 ns | 3 ns |
| andere | 10 ns | 10 ns | 2 ns | 10 ns | 2 ns |
Recovery und Removal sind Datenblatt-Minima über -40 bis 85 C bei 4,5 V (5-V-Familien) oder 3,3 V (LVC), der größere Wert von TI und Nexperia, wenn beide einen angeben:
- HC, HCT: 8 ns trec von
nSD,nRDzunCP, Nexperia 74HC_HCT74 rev 9 (TI SN74HC74 SCLS094F gibt 6 ns an, TI CD74HC74 SCHS124E 8 ns, dort als trem bezeichnet). - AHC, AHCT: 3,5 ns trec von
nRDzunCPfür die 74AHCT74 (3,0 ns für die 74AHC74), Nexperia 74AHC_AHCT74 rev 11 (TI SN74AHC74 SCLS255N gibt 3 ns an). - AC, ACT: 2,4 ns trec bei 5 V, TI CD74AC74 SCHS231E und CD74ACT74 SCHS321A (TI SN74AC74 SCAS521H gibt 0 an).
- LVC: 2 ns Setup von
PREoderCLRinaktiv vorCLK, TI SN74LVC74A SCAS287W (Nexperia 74LVC74A gibt 1,0 ns an). - LS: 25 ns Setup von
CLRinaktiv und 3 ns Hold an jedem Eingang, TI SN74LS161A SDLS060 (die SN74LS74A in SDLS119 listet weder noch).
Keines der oben genannten CMOS-Datenblätter (auch nicht TI SN74HC161 SCLS297D oder Nexperia 74LVC161, deren Hold nur die synchronen Eingänge abdeckt) listet eine Removal-Zeit, daher ist sie dort 0. Die Zeilen für AUP, LV, LVX und andere übernehmen ihr Setup und Hold.
Primitiven nach Name und generische Symbole nehmen 1 ns und kein Setup oder Hold.
Ein benutzerdefiniertes Bauteil erhält ein Modell inline, abgeglichen nach ref oder nach value (jedes Bauteil mit diesem Wert). Mehrere Einträge für ein Bauteil fügen jeweils eine Zelle hinzu (eine pro Gatter eines Quad, zum Beispiel). Ein Eintrag mit nur Timing behält das eingebaute Modell bei und ändert sein Timing.
[[parts]]
ref = "U7"
primitive = "nand" # a primitive; pins map its pin keys to the part's pins
pins = { A = "1", B = "2", Y = "3" }
delay = "3ns" # every output; setup, hold, recovery and removal as well
delays = { Y = "5ns" } # or per output key
[[parts]]
value = "MYBUF8"
primitive = "74HC244" # borrow a library pinout
[[parts]]
ref = "U9"
inputs = ["1", "2", "3"] # pins by number or unique name
outputs = ["4"]
truth = ["000 1", "1-- 0", "01- z"] # first matching row wins; no match (or an x input) gives xPrimitiv-Pinschlüssel (Eingänge, dann Ausgänge); füge _N an einen Schlüssel für einen aktiv niedrigen Pin oder einen invertierten Ausgang an, und lasse einen optionalen Eingang aus, um ihn inaktiv zu halten:
| Primitiv | Eingänge | Ausgänge |
|---|---|---|
and, or, xor, nand, nor, xnor | beliebige Schlüssel außer Y | Y |
not, buf | ein Schlüssel | Y |
jedes Gatter mit _od (nand_od, not_od, buf_od) | wie das Gatter | Y, Open-Drain: 0 oder z |
tri | A, OE | Y (z, wenn OE niedrig ist) |
dff | D, CLK, optional S, R, OE | Q, QN (z, wenn OE niedrig ist) |
jk | J, K, CLK, optional S, R | Q, QN |
sr | S, R | Q, QN |
dlatch | D, EN, optional R, OE | Q, QN (z, wenn OE niedrig ist) |
xcvr | A, B, DIR, optional OE | A, B: dieselbe Pins, von der anderen Seite aus durch DIR gesteuert |
mux2 | I0, I1, S, optional EN | Y |
dec138 | A0, A1, A2, E1, E2, E3 | Y0 bis Y7 |
counter161, counter163 | optional R, CLK, optional D0 bis D3, CEP, LOAD, CET | Q0 bis Q3, TC |
shift164 | A, optional B, CLK, optional R | Q0 bis Q7 |
shift595 | D, CLK, LATCH, optional R, OE | Q0 bis Q7, QS |
Flip-Flops takten auf den steigenden Flanken (Schlüssel CLK_N für die fallende); S und R sind asynchron, und wenn beide aktiv sind, ergibt sich Q = QN = 1, wie bei einem 74HC74. Der 161 setzt sofort zurück, der 163 erst am nächsten Takt. Ein 595 schiebt auf CLK, kopiert auf LATCH auf seine Ausgänge (der Wert vor einem Schiebeprozess zum selben Zeitpunkt) und lässt sie schweben, solange OE niedrig ist.
Die Engine hält vier Pegel vor: 0, 1, x (unbekannt) und z (schwebend). Jedes Netz löst seine Treiber auf: Starke Treiber (Ausgänge, Schienen, Stimulationen), die übereinstimmen, setzen den Pegel. 0 gegen 1 ergibt x und einen gemeldeten Konflikt. Zieh-Widerstände zählen nur, wenn kein starker Treiber aktiv ist. Ein z-Eingang wird als x gelesen. Gatter gehen nur dann auf x, wenn der unbekannte Eingang relevant ist (0 in ein UND ergibt 0), und ein Flip-Flop, das durch eine unsichere Flanke getaktet wird (0 zu x oder x zu 1), geht auf x, es sei denn, es behält seinen Wert. Jeder Ausgang hat seine eigene Verzögerung (Transport, sodass Pulse kürzer als die Verzögerung durchkommen). Ereignisse laufen in Zeitreihenfolge ab, und Änderungen mit null Verzögerung stabilisieren sich in Delta-Zyklen zum selben Zeitpunkt. Eine Schleife mit null Verzögerung, die nach 1000 Delta-Zyklen noch immer Änderungen aufweist, stoppt die Ausführung und meldet die Netze. Gleiches gilt für eine Ausführung, die über 50 Millionen Ereignisse hinausgeht.
Flip-Flops, Zähler und Schieberegister prüfen Setup und Hold an ihren getakteten Eingängen anhand der Timing-Parameter des Modells: Ein Dateneingang, der weniger als setup vor einer steigenden Taktflanke oder weniger als hold danach geändert wurde, ist eine Verletzung (während einer aktiven asynchronen Reset- oder Set-Flanke nicht geprüft). Ein D-Latch prüft seinen D-Eingang auf dieselbe Weise gegen die schließende (fallende) Flanke von EN. Ein asynchroner Reset oder Set, der weniger als recovery vor einer Taktflanke oder weniger als removal danach freigegeben wird, ist ebenfalls eine Verletzung, mit den Recovery- und Removal-Werten aus der Familientabelle. Ein 595 erwartet außerdem, dass die steigende Flanke seines LATCH (RCLK) mindestens setup nach der letzten steigenden Flanke von CLK (SRCLK) liegt. Wenn die beiden Takte zusammengebunden sind (dieselbe Zeit), ist das in Ordnung und latched den Wert vor dem Schiebeprozess.
Bei einer Verletzung geht der Flip-Flop, Latch oder Register, den die Prüfung abdeckt, auf x, wie die Verilog-Modelle mit ihren Benachrichtigern, bis er wieder sauber getaktet, gesetzt oder zurückgesetzt wird. Setze on_violation = "keep" auf der Simulation, um die Verletzung zu melden und den abgetasteten Wert beizubehalten.
Messwerte: bestandene und fehlgeschlagene Assertions, Konflikte, Timing-Verletzungen, Zellen und Ereignisse. Die Prüfung listet jede fehlgeschlagene Assertion, jeden Konflikt, jede Timing-Verletzung oder jeden gestoppten Lauf als Fehler auf der Simulation, solange das Ergebnis aktuell ist. Das Ergebnis wird veraltet, wenn die Spezifikation oder das Netzliste des Schaltplans sich ändert. examples/logic enthält zwei: counter, ein 74HC161, der in einen 74HC138 zählt, und i2c, ein Open-Drain-Bus, auf dem ein Controller (zwei 74LVC1G07) und ein Ziel (ein 74LVC1G06, der SDA für sein ACK niedrig zieht) 4,7k-Pull-ups teilen, und ein 74HC595, der von SCL getaktet wird, das Byte erfasst, geprüft auf START, die Bits, das ACK, das Byte (ein record-Bus) und STOP.