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);
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.
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.
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.
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.
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
foriin0to2**4-1loop
2
forkin0to2**4-1loop
3
a<=std_logic_vector(to_unsigned(i,4));
4
b<=std_logic_vector(to_unsigned(k,4));
5
6
waitfor0ns;
7
8
ifunsigned(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
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).
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?
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>kandc1='1'andc0='0')
2
report"error at "&integer'image(i)&">"&integer'image(k);
3
4
assert(i<kandc1='0'andc0='1')
5
report"error at "&integer'image(i)&"<"&integer'image(k);
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.
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
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?
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.
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...