VHDL: Problem bei assert Anweisung

OP #6088552
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:
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 #6088600
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.
Moderator (Firma: Titel) Persönliche Seite #6088607
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:
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 #6088722
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?
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 #6089219
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:
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 #6089325
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.
Moderator (Firma: Titel) Persönliche Seite #6089424
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
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren