mikrocontroller.net

Forum: FPGA, VHDL & Co. Verilog-Simulation ergibt merkwürdiges Ergebnis


Autor: Frank Hans (gowi)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe ein scheinbar einfaches Verilog-Modul in Quartus II 
geschrieben:
module test(CLOCK, RESET, GO, clk_en, DATA, zaehler);

input CLOCK, RESET, GO, clk_en;
input [15:0] DATA;
output[15:0] zaehler;

wire CLOCK, RESET, clk_en, GO;
wire [15:0] DATA;
reg [15:0] zaehler;
reg [3:0] state;

always @(posedge RESET or posedge CLOCK) begin
      if (RESET) begin
        zaehler <= 16'b0;
        state <= 0;
      end else
      if (clk_en) begin
        if (state == 0 & GO) begin
          zaehler <= DATA;
          state <= 1;
        end
      end
end
endmodule

Der Code ist etwas reduziert, verändert aber das Ergebnis nicht. Im
State 0 soll (wenn GO anliegt), DATA an das zaehler-Register geschrieben
werden. Das Ergebnis ist aber im Anhang gezeigt. Anstatt 0xFFFF liegt an
zaehler 0x3FFF an. Kann sich das jemand erklären?

Autor: Schrotty (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ich noch erstaunlicher finde, ist die Tatsache, dass die einzelnen 
Bits deines Zählers zu scheinbar völlig willkürlichen Zeitpunkten ihren 
Zustand wechseln. Und das auch noch komplett asynchron zu den ganzen 
"Steuersignalen"

Wie hast denn das hinbekommen?

Führst du hier vielleicht gerade eine Back-Anotation-Simulation durch?

Autor: Frank Hans (gowi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das finde ich schon weniger verwunderlich. Die Simulation berücksichtigt 
ja die konkrete Synthese und Platzierung auf dem Ziel-FPGA. Und durch 
unterschiedliche Signal- und Gatterlaufzeiten kann es schon zu einigen 
Nanosekunden Unterschied beim Flankenwechsel kommen. Wichtig ist nur, 
dass alle Wechsel bis zur nächsten positiven Taktflanke erfolgt sind.

Autor: Schrotty (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Die Simulation berücksichtigt ja die konkrete Synthese und Platzierung auf >dem 
Ziel-FPGA.

Aber nicht die funktionale Simulation, sondern erst die 
Backanotation-Simulation.
Oder wird in Quartus nicht funktional simuliert?

Zu deinem Problem:
Ich kenne mich mit Verilog nicht wirklich aus, aber diese Zeile kommt 
mir seltsam vor:

always @(posedge RESET or posedge CLOCK) begin

Wenn tatsächlich synthetisiert wird, dann wird dieser Code vermutlich 
ein schlechtes Ergebnis bringen.
Es wird ein Register mit der einen ODER der anderen Flanke geschaltet.
Das führt auf jeden Fall zu einem asynchronen Design, wenn die Synthese 
es überhaupt akzeptiert hat.

In einem synchronen Design schalten ALLE Register mit dem gleichen Takt 
und bitte NUR mit diesem Takt.

Probier´s mal so:

always @ (posedge CLOCK) begin

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist das Gegenteil von inaktzeptabel? Klar: akzeptabel.
Was ist das Gegenteil von intolerant?    Klar: tolerant.
Was ist das Gegenteil von intuitiv?   Logisch: ... ;-)

Ich finde Verilog mit seinen Sensitivlisten so sehr tuitiv, denn mit der 
Zeile:
>>> always @(posedge RESET or posedge CLOCK) begin
wird ein asynchroner high-aktiver Reset und ein auf die steigende Flanke 
sensitiver Takt beschrieben. Nur ist hier irgendwie die fallende Flanke 
oder gar der Pegel des Reset laut Beschreibung gar nicht weiter 
interessant.
Siehe dazu auch http://de.wikipedia.org/wiki/Verilog
Ich kann mir jetzt gerade gar kein Bauteil vorstellen, das mit einer 
steigenden Flanke zurückgesetzt wird, der Pegel dieses Reset-Signals 
danach aber uninteressant ist  :-o
Dass der Reset aber durchaus pegelsensitiv implementiert werden wird, 
ist implizites Wissen, das ich zum Verstehen einer Verilog-Beschreibung 
unbedingt brauche.

Zum Thema:
Mich würde mal das Laufzeitverhalten des Signals state brennend 
interessieren. Und natürlich wäre eine Verhaltenssimulation statt 
einer Post-Route-Simulation als erster Schritt auch nicht ohne.

Autor: Morin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich kann mir jetzt gerade gar kein Bauteil vorstellen, das mit einer
> steigenden Flanke zurückgesetzt wird, der Pegel dieses Reset-Signals
> danach aber uninteressant ist  :-o

Ich schon: Nach einer steigenden Flanke ist der Pegel immer "high". Da 
der Pegel eh immer derselbe ist, ist er auch nicht mehr interessant. Das 
wird ja mit der Clock genauso gemacht.

Ob die Tools das genauso sehen steht natürlich auf einem anderen 
Blatt...

Spielt aber hier keine Rolle: Da auf zwei verschiedene Signale 
gleichzeitig gewartet wird, muss danach überprüft werden, welches denn 
nun eine Flanke hatte.

Autor: SuperWilly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ein paar Anmerkungen:

1. Die wires sind unnötig.
2. Sind "GO", "clk_en", "DATA" taktsynchron ?


module test(CLOCK, RESET, GO, clk_en, DATA, zaehler);

input CLOCK, RESET, GO, clk_en;
input [15:0] DATA;
output[15:0] zaehler;

reg [15:0] zaehler;
reg [3:0] state;

always @(posedge RESET or posedge CLOCK) begin
      if (RESET) begin
        zaehler <= 16'b0;
        state <= 0;
      end else
      if (clk_en) begin
        if (state == 0 & GO) begin
          zaehler <= DATA;
          state <= 1;
        end
      end
end
endmodule



Gruß,
SuperWilly

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Morin schrieb:
> Ich schon: Nach einer steigenden Flanke ist der Pegel immer "high". Da
> der Pegel eh immer derselbe ist, ist er auch nicht mehr interessant. Das
> wird ja mit der Clock genauso gemacht.
Ok. Klar, jetzt :-/
Aber trotzdem tuitiv...
Warum werden dann bei Verilog nicht wie bei VHDL üblich nur die Signale 
in die Sensitivliste aufgenommen und die Flankenabhängigkeit im 
Quelltext aufgeführt? Ich könnte doch auch so schreiben:
always @(RESET or CLOCK) begin
  if (RESET) begin      *** pegelsensitiv
    :
  end else
    if (CLOCK) begin    *** steigende Flanke
       :
    end
  end
end

Autor: SuperWilly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Schrotty
--Es wird ein Register mit der einen ODER der anderen Flanke geschaltet.

Falsch!

always @(posedge RESET or posedge CLOCK)
begin
    if (RESET) begin
      
    end else
    if (clk_en) begin
       
    end
end
endmodule


ist in VHDL mit einem getakteten Prozess mit asynchronem Reset 
gleichzusetzen:

process(RESET, CLOCK)
begin
    if RESET = '1' then


    elsif rising_edge(CLOCK) then

        if clk_en = '1' then

        end if;

    end if;
end process;

Gruß,
SuperWilly

Autor: Igor (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Selbst ohne Verbesserungen klappt dieser Code bei mir vollkommen 
korrekt.
Quartus 4.1, Device - EP1C3T100C6

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Igor schrieb:
> Quartus 4.1, Device - EP1C3T100C6
Du hast deutlich kürzere Verzögerungszeiten (5ns statt 10 ns).
Im Bild  Frank Hans (gowi) sind es 10ns. Aber der Reset geht nur 5ns vor 
der steigenden Flanke vom Clock weg. Evtl. ist das zu knapp...

Was passiert, wenn du den Zeitpunkt, an dem der Reset inaktiv wird, in 
deiner Post-Route-Simulation auf 57 oder 58 ns setzt?

Autor: Frank Hans (gowi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist (fast) das Problem!
Wird der Reset eher inaktiv, ändert das nichts am Verhalten. Wenn ich 
aber clk_en und GO eher auf HIGH setze, dann erhalte ich das erwartete 
Simulationsergebnis.

Also war das Problem, dass der Wechsel der Steuersignale auf den 
HIGH-Pegel die Setup-Time der entsprechende Flipflops verletzt hat?
In meinem Gesamtdesign sollte das dann nicht vorkommen, weil die 
Steuersignale taktsynchron erzeugt werden.

Aber was ist, wenn die Steuersignale extern erzeugt werden? Dann kann im 
worst-case doch durchaus das Simulations-Szenario eintreten? Müssten 
dann diese Signale erst "einsynchronisiert" werden?

Autor: Igor (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller schrieb:
> Was passiert, wenn du den Zeitpunkt, an dem der Reset inaktiv wird, in
deiner Post-Route-Simulation auf 57 oder 58 ns setzt?

Es ist nichts passiert.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank Hans schrieb:
> Also war das Problem, dass der Wechsel der Steuersignale auf den
> HIGH-Pegel die Setup-Time der entsprechende Flipflops verletzt hat?
Asynchrone Resets sind allgemein schlecht, weil sie durch 
unterschiedliche Laufzeiten unterschiedlich schnell an den FFs ankommen 
und insbesondere auch inaktiv werden. Ich habe da mal einen einfachen 
Aufbau dazu gemacht, der in der Praxis genau das von dir beschriebene 
Verhalten aufweist:
http://www.lothar-miller.de/s9y/archives/70-Asynch...

Igor schrieb:
> Es ist nichts passiert.
Dann hängt es an den Laufzeiten der asynchronen Steuersignale...
Da hilft nur: Einsynchronisieren.

Autor: Schrotty (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@SuperWilly:
Danke für den Hinweis.. wie gesagt, ich hab keine Ahnung von Verilog, 
aber mit ist das eben sofort in´s Auge gestochen.. aber mir war da nicht 
klar, dass es sich um eine sensitivity-List wie bei einem process 
handelt.
Bin halt doch ein VHDL-Kind :-)
Aber so lernt man nie aus...

@Lothar Miller:
tuitiv scheint hier wirklich das passende Wort zu sein.. sollen sich die 
Amis damit rumschlagen, ich bleib beim VHDL :-)

Autor: Marcus Harnisch (mharnisch) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller schrieb:
> Morin schrieb:
>> Ich schon: Nach einer steigenden Flanke ist der Pegel immer "high". Da
>> der Pegel eh immer derselbe ist, ist er auch nicht mehr interessant. Das
>> wird ja mit der Clock genauso gemacht.
> Ok. Klar, jetzt :-/

Klar ist der Pegel interessant. Der wird jedesmal abgefragt, wenn 
während des Reset eine Taktflanke auftritt. Daher geht auch das hier 
nicht:
always @(RESET or posedge CLOCK)
begin
    if (RESET)
    ...
    else if (CLOCK)
    ...
end

Wenn RESET deaktiviert wird, während CLOCK==1, dann wird der else-if 
Zweig ausgeführt.

> Aber trotzdem tuitiv...

Das kommt auf den Standpunkt an.

> Warum werden dann bei Verilog nicht wie bei VHDL üblich nur die Signale
> in die Sensitivliste aufgenommen und die Flankenabhängigkeit im
> Quelltext aufgeführt?

Genauso könnte man die Frage stellen, warum VHDL es nicht genauso wie 
Verilog macht. Diese Argumentation ist zwecklos.

Gruß
Marcus

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.