VHDL: Problem bei assert Anweisung

OP #6088552
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:
1
begin
2
TEST: entity forBitComperator port map(a, b, c1, c0);
3
  process
4
  begin
5
    for i in 0 to 2**4 loop
6
        for k in 0 to 2**4 loop
7
            a <= std_logic_vector(to_unsigned(i, 4));
8
            b <= std_logic_vector(to_unsigned(k, 4));
9
            
10
            if unsigned(a) > unsigned(b) then
11
              assert(c1 = '1' and c0 ='0')
12
              report "error";
13
             
14
             elsif unsigned(a) < unsigned(b) then
15
               assert(c1 = '0' and c0 ='1')
16
               report "error" ;
17
               
18
             elsif unsigned(a) = unsigned(b) then
19
               assert(c1 = '0' and c0 ='0')
20
               report "error" ;

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

Danke im Voraus.

Grüße,
Holocron
Gast
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.
Moderator (Firma: Titel) Persönliche Seite
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:
1
    for i in 0 to 2**4-1 loop
2
        for k in 0 to 2**4-1 loop
3
            a <= std_logic_vector(to_unsigned(i, 4));
4
            b <= std_logic_vector(to_unsigned(k, 4));
5

6
            wait for 0 ns;
7

8
            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
Angehängte Dateien:
OP
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).
OP
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?
1
begin
2
TEST: entity forBitComperator port map(a, b, c1, c0);
3
  process
4
  begin
5
    for i in 0 to 2**4-1 loop --a
6
        for k in 0 to 2**4-1 loop --b
7
            a <= std_logic_vector(to_unsigned(i, 4));
8
            b <= std_logic_vector(to_unsigned(k, 4));
9

10
            wait for 0 ns;
11

12
            if i > k then
13
              assert(c1 = '1' and c0 = '0')
14
              report "error " & integer'image(i) 
15
                     & ">" & integer'image(k);
16
(...)
17
end;
Moderator (Firma: Titel) Persönliche Seite
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:
1
              assert(i>k and c1='1' and c0='0')
2
                 report "error at " & integer'image(i) & ">" & integer'image(k);
3

4
              assert(i<k and c1='0' and c0='1')
5
                 report "error at " & integer'image(i) & "<" & integer'image(k);
OP
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.
Moderator (Firma: Titel) Persönliche Seite
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
Angehängte Dateien:
OP
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?
Angehängte Dateien:

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.