Kosimulation digitaler und analoger Schaltungen: Zwei Ansätze für die Icarus-Verilog- und NGSpice-Brücke
Moderne elektronische Systeme erfordern die Integration digitaler und analoger Komponenten, weshalb die Mixed-Signal-Simulation von entscheidender Bedeutung ist. Um diese Herausforderung zu meistern, haben wir eine Brücke zwischen Icarus Verilog und NGSpice implementiert, indem wir zwei Architekturen entwickelt haben. Jede hat fundamentale Einschränkungen, aber sie ermöglichen bereits die Lösung realer Aufgaben – von SAR-ADCs bis zu Sigma-Delta-Modulatoren.
Grundlagen der Mixed-Signal-Simulation: Ereignisse vs. Kontinuität
Digitale Schaltungen werden ereignisgesteuert modelliert: Der Simulator aktiviert sich nur bei Signaländerungen (Taktflanken, Flipflop-Umschaltungen). Genau so arbeiten Icarus Verilog und andere digitale Simulatoren – das System „schläft“ zwischen Ereignissen und gewährleistet dadurch hohe Performance. Analoge Schaltungen benötigen eine kontinuierliche Modellierung: SPICE-Engines (NGSpice, Spectre) zerlegen die Zeit in kleine Schritte und lösen Differentialgleichungen für jedes Intervall. Dieser Ansatz ist präzise, aber ressourcenintensiv, insbesondere bei scharfen Flanken oder Rückkopplungsschleifen.
Die zentrale Herausforderung bei der Kosimulation liegt darin, diese grundlegend unterschiedlichen Paradigmen zu vereinbaren. Der digitale Simulator bearbeitet diskrete Ereignisse, während der analoge Simulator einen fließenden Zeitverlauf benötigt. Bei der Kombination eines SAR-ADC (bei dem ein analoger Komparator mit digitaler Logik interagiert) entsteht ein Dilemma: Wie überträgt man Daten zwischen den Engines, ohne kritische Ereignisse zu verpassen?
Brückenarchitektur: Gemeinsame Prinzipien
Beide Implementierungen nutzen die gleichen Kerntechnologien:
- VPI (Verilog Procedural Interface) zur Interaktion mit Icarus
- Die dynamische Bibliothek libngspice.so
- Ein Streaming-Mechanismus mit Semaphoren
- Einen separaten NGSpice-Ausführungs-Thread
Das zentrale Element ist die Systemaufgabe $spice_sync(), die bei Taktflanken aufgerufen wird. Sie führt einen vollständigen Austauschzyklus durch: Übermittlung digitaler Werte an SPICE per alter-Befehlen, Abfrage analoger Spannungen und Aktualisierung realer Variablen in Verilog. Dadurch lassen sich analoge Signale in GTKWave auf derselben Zeitleiste wie digitale anzeigen.
always @(posedge clk_fast) begin
$spice_sync();
if (tb.Vcmp > vref_th) begin
// Reaction to event
...
end
end
Der Mechanismus expose_analog_N synchronisiert analoge Variablen automatisch und macht sie für die digitale Logik zugänglich. Wrapper-Objekte auf beiden Seiten der Brücke handhaben Flanken und Verzögerungen.
Klassischer Ansatz: Synchrone Abfrage
In dieser Implementierung initiiert Verilog den Austausch bei jedem Aufruf von $spice_sync(). Der Simulator protokolliert die aktuelle Zeit, blockiert auf einem Semaphore, übergibt die Kontrolle an NGSpice, das bis zu diesem Punkt simuliert und die Daten zurückgibt.
Vorteile:
- Volle Deterministik
- Vorhersehbare Performance
- Einfache Umsetzung (ca. 2000 Codezeilen)
Kritische Einschränkungen:
- Vollständige Unsichtbarkeit analoger Ereignisse zwischen Taktflanken. Wenn z. B. ein Komparator bei 5,2 ns umschaltet und die nächste Taktflanke bei 10,0 ns erfolgt, erkennt die digitale Logik die Änderung erst nach 4,8 ns nicht – Rückkopplungsschleifen in SAR-ADCs oder DC-DC-Wandlern werden unmöglich.
- Erzwungenes Oversampling: Um schnelle Ereignisse zu erfassen, muss die Taktfrequenz künstlich erhöht werden (z. B. auf 500 MHz), was die Performance beeinträchtigt.
Dieser Ansatz eignet sich nur für Aufgaben, bei denen analoge Ereignisse mit Taktflanken übereinstimmen oder eine Hochfrequenz-Taktung zur Synchronisation verwendet wird.
Alternativer Ansatz: Lookahead-Analyse
Um die Einschränkungen des klassischen Verfahrens zu überwinden, haben wir einen Lookahead-Mechanismus implementiert. NGSpice erhält die Erlaubnis, um ein festgelegtes Intervall „vorzulaufen“, und überwacht analoge Ereignisse über konfigurierbare Sensoren. Beispielregel in mixed_bridge.cfg:
analog_event_0 = threshold outp rising 1.2 | time_var=tb.analog_event_time id_var=tb.analog_event_id
Wird die Bedingung erfüllt, pausiert SPICE und löst ein Ereignis in Verilog über den cbAfterDelay-Callback aus.
Vorteile:
- Erkennung asynchroner analoger Ereignisse
- Konfigurierbare Flexibilität (Schwellwerte, Dauern, Energiebedingungen)
- Geringere Belastung bei seltenen Takten
Fundamentale Nachteile:
- Verpasste Ereignisse zwischen SPICE-Schritten aufgrund diskreter Zeitintegration
- Kausalitätsverletzungen:
alter-Befehle (digitale Signaländerungen) wirken erst in der nächsten Simulationsphase, was für DACs kritisch ist - Limit von einem Ereignis pro Analysefenster
- Nichtdeterminismus durch Heuristiken bei der Wahl der Lookahead-Intervalllänge
- Hohe Implementierungs-Komplexität (über 3500 Codezeilen + Config-Parser)
Wichtige Unterschiede im Vergleich
Die Haupt-Abwägungen zwischen den Architekturen zeigen sich in fünf Aspekten:
- Ereigniserkennung: Der klassische Ansatz verpasst Ereignisse zwischen Takten vollständig, der alternative erfasst sie teilweise, riskiert aber Fehlschläge
- Kausalität: Im klassischen Ansatz ist die DAC→Analog-Verknüpfung korrekt; im alternativen können Timing-Fehlanpassungen auftreten
- Performance: Die synchrone Methode bietet stabile Geschwindigkeit; Lookahead kann bei kurzen Intervallen dramatisch verlangsamen
- Determinismus: Nur die klassische Implementierung garantiert reproduzierbare Ergebnisse
- Integrationskomplexität: Der alternative Ansatz erfordert Feinabstimmung von Heuristiken und Analyse der Schaltungstiming
Wichtige Erkenntnisse
- Keine perfekte Lösung: Beide Architekturen haben inhärente Einschränkungen aufgrund grundlegender Unterschiede in den Modellierungs-Paradigmen
- Auswahl abhängig von der Aufgabe: Der alternative Ansatz eignet sich für Sigma-Delta-Modulatoren mit seltenen Pulsen; der klassische mit Oversampling passt zu SAR-ADCs mit strengen Timing-Anforderungen
- Praxisrelevanz: Das Tool wird bereits zur Verifikation digitaler Logik in analogen Umgebungen und zum Pulszählen eingesetzt
- Visualisierung: Beide unterstützen die kombinierte Anzeige von Signalen in GTKWave und gnuplot auf einer einheitlichen Zeitleiste
- Ausblick: Die Integration einer Ereigniswarteschlange und die Nutzung von
cbNextSimTimekönnten Einschränkungen mildern
Praktische Implementierung und Anwendungsbeispiel
Stellen Sie sich vor, die Brücke für einen Sigma-Delta-Modulator zu nutzen. Der analoge Teil erzeugt kurze Pulse, die ein digitaler Zähler erfassen muss. Im klassischen Ansatz rufen Sie einfach $spice_sync() mit einer Frequenz auf, die die Pulsdauer übersteigt. Beispiel-Verilog-Code:
module DSMCounter(
input i_clk,
input i_rst,
input i_Qbar,
output reg[31:0] o_cntQbar,
output reg o_ready
);
parameter CNT_CLK = 22;
reg [31:0] cnt;
reg [31:0] cntQbar;
always @(posedge i_clk) begin
if(i_rst) begin
cnt <= 0;
cntQbar <= 0;
o_cntQbar <= 0;
o_ready <= 0;
end else begin
o_ready <= 0;
if(i_Qbar == 1) begin
cntQbar <= cntQbar + 1;
end
if(cnt == CNT_CLK-1) begin
o_cntQbar <= cntQbar;
o_ready <= 1;
cnt <= 0;
cntQbar <= 0;
end else begin
cnt <= cnt + 1;
end
end
end
endmodule
In der alternativen Implementierung können Sie die Sync-Frequenz mit Pulsdetektionsregeln über analog_event senken. Dies erfordert jedoch sorgfältige Abstimmung der Lookahead-Parameter, um Verpasser zu vermeiden.
Zum Ausführen benötigen Sie den shared NGSpice-Build (--with-ngshared). Die Brückenkonfiguration erfolgt über mixed_bridge.cfg, die Sync-Punkte und Ereigniserkennungsregeln definiert. Beide Implementierungen sind Open-Source, erfordern aber Tests für Ihre spezifische Aufgabe.
Zukünftige Entwicklungen umfassen die Implementierung einer Ereigniswarteschlange statt einer einzelnen Flagge, die Integration von maxstep in die Brückenkonfiguration und die Nutzung von cbNextSimTime für präzise Zeitsteuerung. Eine vollständige Lösung erfordert die Ergänzung einer Event-API in NGSpice.
— Editorial Team
Noch keine Kommentare.