Hardwarebeschreibungssprachen und Verifikation
always @(*) begin
sum = sum + in;
endDer obige Code wurde in der Absicht geschrieben, einen Akkumulator zu bauen, der den Eingang in fortlaufend aufaddiert. Welche Kombination aus dem Problem dieses Codes und seiner Korrektur ist richtig?
- AEs gibt kein Problem; es wird eine Schaltung synthetisiert, die sum bei jeder Änderung von in einmal um in erhöht
- BIn der Sensitivitätsliste fehlt ein Signal, sodass Simulation und Synthese voneinander abweichen; man schreibt stattdessen @(in)
- CDer Ausgang des Addierers wird ohne Flipflop auf seinen eigenen Eingang zurückgeführt, sodass sich der Wert nie stabilisiert; man schreibt sum <= sum + in; innerhalb von always @(posedge clk), um einmal pro Takt zu addieren
Antwort und Erläuterung anzeigen
Antwort: C. Der Ausgang des Addierers wird ohne Flipflop auf seinen eigenen Eingang zurückgeführt, sodass sich der Wert nie stabilisiert; man schreibt sum <= sum + in; innerhalb von always @(posedge clk), um einmal pro Takt zu addieren
always @(*) beschreibt eine kombinatorische Schaltung, daher ergibt dieser Code eine Schaltung, in der ein Addierer mit sum als Eingang mit seinem Ausgang direkt sum treibt. Ohne Flipflop ändert jede Änderung am Ausgang des Addierers seinen Eingang, und der Wert läuft immer weiter um, ohne sich zu stabilisieren: Es entsteht eine kombinatorische Schleife. Die statische Timing-Analyse kann damit nicht umgehen, und viele Werkzeuge für Lint und Logiksynthese geben Warnungen oder Fehler aus. Eine Schaltung, die Werte aufsummiert, braucht ein Flipflop, das den Wert bei jeder steigenden Taktflanke einmal aktualisiert: Man verwendet eine nicht blockierende Zuweisung innerhalb von always @(posedge clk) und setzt den Anfangswert per Reset.
Weiter: 9 weitere Fragen zu Hardwarebeschreibungssprachen und Verifikation