mikrocontroller.net

Forum: FPGA, VHDL & Co. VHDL: Problem bei assert Anweisung


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Jonas B. (holocron)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich musste einen 4 Bit Vergleicher in VHDL entwerfen und mit assert in 
der testbench das ganze prüfen, allerdings klappt das nicht so recht. Es 
kommt für eine bestimmte Belegung (der Fall a<b) assert zu Folge immer 
ein Fehler (obwohl alles stimmt) - wenn ich hingegen tatsächlich mit 
Absicht einen Fehler einbaue, ist nach assert alles richtig. Hat jemand 
eine Idee, woran das liegen könnte? Hier wäre ein Auszug der Testbench. 
Der vollständige Code ist im Link unten:
begin
TEST: entity forBitComperator port map(a, b, c1, c0);
  process
  begin
    for i in 0 to 2**4 loop
        for k in 0 to 2**4 loop
            a <= std_logic_vector(to_unsigned(i, 4));
            b <= std_logic_vector(to_unsigned(k, 4));
            
            if unsigned(a) > unsigned(b) then
              assert(c1 = '1' and c0 ='0')
              report "error";
             
             elsif unsigned(a) < unsigned(b) then
               assert(c1 = '0' and c0 ='1')
               report "error" ;
               
             elsif unsigned(a) = unsigned(b) then
               assert(c1 = '0' and c0 ='0')
               report "error" ;

https://www.edaplayground.com/x/4c2n

Danke im Voraus.

Grüße,
Holocron

von Mampf F. (mampf) Benutzerseite


Bewertung
1 lesenswert
nicht lesenswert
Jonas B. schrieb:
> for i in 0 to 2**4 loop
>         for k in 0 to 2**4 loop

spontant ist mir nur aufgefallen, dass du vermutlich 2**4-1 meinst.

for i in 0 to 3 zählt 0, 1, 2, 3 und 2**4 ist mehr als 4 bit.

von Jonas B. (holocron)


Bewertung
0 lesenswert
nicht lesenswert
Oh stimmt, danke. Ein Problem wäre damit gelöst.
Aber es tritt immer noch eine Assert Meldung auf. Allerdings nur in 
Zeile 29, weswegen ich nicht wirklich sehe warum speziell Zeile 29 Ärger 
macht.

: Bearbeitet durch User
von Daniel__m (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi, ich denke, das hat etwas mit Deltazyklen zu tun. Der Prozess wird 
gestartet, sobald sich ein Signal ändert (zb a oder b). Zu diesem 
Zeitpunkt sind c0 und c1 noch nicht evaluiert, da die auch erst durch a 
bzw. b getriggert werden. Der Testprozess wird also (mind.) 2x 
durchlaufen und beim ersten mal noch mit alten c-Werten.

von Jonas B. (holocron)


Bewertung
0 lesenswert
nicht lesenswert
Ah okay, das macht natürlich Sinn. Könnte ich das lösen, indem ich ein 
wait statement einbaue?
Hatte überlegt es vor der assert Zuweisung einzubauen, das hat 
allerdings nichts geholfen.

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Jonas B. schrieb:
> forBitComperator
Du kannst dort als Namen auch deutsche Worte verwenden, wenn du dir mit 
dem Englischen ein etwas schwer tust. Denn ein Vierbitkomparator heißt 
bei den Angelsachsen eher FourBitComparator (four von vier und 
comparator von compare).

> for i in 0 to 2**4 loop
16 passt nicht in 4 Bits, du hast da den gern verwendeten off-by-one 
Fehler produziert. Da gehört eigentlich ein "... to 2**4-1 loop" hin.

> report "error" ;
Wäre es nicht sinnvoll, dort für unterschiedliche Fehler auch 
unterschiedliche Fehlermeldungen auszugeben. Denn so kannst du ja den 
einen vom anderen Fehler gar nicht unterscheiden. Dass dann die Ports 
der Komparatoren nichtssagende einbuchstabige Namen haben, macht die 
Sache nicht wesentlich durchschaubarer. Und dass die Fehler im Prinzip 
auch keine Fehler sind, verbessert die Lage nicht grundlegend...

> Hat jemand eine Idee, woran das liegen könnte?
Ich würde da mal ein "wait" einbauen:
    for i in 0 to 2**4-1 loop
        for k in 0 to 2**4-1 loop
            a <= std_logic_vector(to_unsigned(i, 4));
            b <= std_logic_vector(to_unsigned(k, 4));

            wait for 0 ns;

            if unsigned(a) > unsigned(b) then
Denn in einem Prozess übernehmen Signale erst beim nächsten wait oder am 
Prozessende den jeweils zuletzt zugewiesenen Zustand. Ohne dieses wait 
wird der Prozess immer mit den Defaultwerten "0000" und "1011" 
durchlaufen.

Wenn man statt nur "error" auch noch die Werte der verglichenen Zahlen 
ausgibt, dann wird das klarer:
https://www.edaplayground.com/x/2cPn

: Bearbeitet durch Moderator
von Jonas B. (holocron)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
danke für das ausführliche Feedback, ich hab dementsprechend meinen Code 
ein wenig angepasst. Allerdings bekomme ich nach wie vor die assert 
Meldungen, aber sieht für mich sehr danach aus, als wäre mein VHDL Code 
fehlerhaft (muss nur noch finden, wo er gescheitert ist).

: Bearbeitet durch User
von Jonas B. (holocron)


Bewertung
0 lesenswert
nicht lesenswert
Ich bin nochmal den Code durchgegangen und es war tatsächlich ein Fehler 
drin, jetzt ist alles korrekt. Assert zu Folge sind allerdings jetzt 
alle 256 Eingangsbelegungen falsch (was natürlich nicht korrekt ist, da 
ich von Hand ein paar simuliert hab). Die Testbench ist auch 
entsprechend der Hinweise korrigiert. Ist vielleicht playground einfach 
defekt/hat einen Server Bug beim simulieren?
begin
TEST: entity forBitComperator port map(a, b, c1, c0);
  process
  begin
    for i in 0 to 2**4-1 loop --a
        for k in 0 to 2**4-1 loop --b
            a <= std_logic_vector(to_unsigned(i, 4));
            b <= std_logic_vector(to_unsigned(k, 4));

            wait for 0 ns;

            if i > k then
              assert(c1 = '1' and c0 = '0')
              report "error " & integer'image(i) 
                     & ">" & integer'image(k);
(...)
end;

: Bearbeitet durch User
von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Jonas B. schrieb:
> Assert zu Folge sind allerdings jetzt alle 256 Eingangsbelegungen falsch
Was machen denn überhaupt diese nicht näher beschriebenen c0 und c1?

Und warum packst du die Abfragen nicht einfach in 3 Abfragen ohne die if 
und else?
So etwa:
              assert(i>k and c1='1' and c0='0')
                 report "error at " & integer'image(i) & ">" & integer'image(k);

              assert(i<k and c1='0' and c0='1')
                 report "error at " & integer'image(i) & "<" & integer'image(k);

: Bearbeitet durch Moderator
von Jonas B. (holocron)


Bewertung
0 lesenswert
nicht lesenswert
c0 und c1 sind die Outputs meines Schaltkreises. Die Spezifikation ist, 
dass man zwei 4-Bitwörter a,b hat und die Schaltung 10 (also c1=1, c0=0) 
ausgibt, falls a > b; 01 (c1=0, c0=1) falls a < b und 00 (c1=c0=0) falls 
a=b gilt.

Oh das geht, war mir nicht sicher ob das korrekt ist. Danke für den 
Tipp.

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Jonas B. schrieb:
> Oh das geht, war mir nicht sicher ob das korrekt ist.
Es geht schon, ist aber hier nicht so richtig zielführend.

Jonas B. schrieb:
> Assert zu Folge sind allerdings jetzt alle 256 Eingangsbelegungen falsch
Das liegt noch am "wait for 0 ns". Da muss offenbar mehr Zeit rein, dass 
der Simulator seine Deltazyklen abhandeln kann.

> (was natürlich nicht korrekt ist, da ich von Hand ein paar simuliert hab).
Da hast du scheinbar ein "glückliches Händchen" gehabt. Mit einem "wait 
for 1 ns" werden jetzt "nur" noch etwa die Hälfte der Abfragen 
angemäkelt. Trotzdem funktioniert der Komparator nicht annähernd so gut, 
wie du es erwartest:
https://www.edaplayground.com/x/5DSP

von Jonas B. (holocron)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
oh stimmt, ja das war noch eine ältere Version vom Code, da war die 
logische Funktion für c1 und c0 falsch. Jetzt funktioniert alles, vielen 
Dank für die Hilfe.

Gibt es irgendeine Regel, wie groß man am besten die wait Zyklen setzen 
sollte?

von Mampf F. (mampf) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Jonas B. schrieb:
> Gibt es irgendeine Regel, wie groß man am besten die wait Zyklen setzen
> sollte?

In der Simulation deiner Testbench dürfte das egal sein.

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Mampf F. schrieb:
> In der Simulation deiner Testbench dürfte das egal sein.
Ich würde auf jeden Fall mehr als "0 ns" nehmen, damit die Deltazyklen 
alle abgearbeitet sind...

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.

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