Hallo
ich probiere seit lange wieder mal was mit meinem DE0.
Das letzte mal habe ich den VGA-Controller nicht hinbekommen und wollte
es jetzt weiterversuchen.
Ich habe beim letzten Mal den Fehler gemacht, alles in eine Datei bzw.
in eine Entity zu schreiben.
Jetzt habe ich als erstes die signals-Entity geschrieben, welche das
vsync und das hsync signal ausgibt.
Ich habe das ganze simuliert, allerdings zählt der Zähler überhaupt
nicht so wie er soll und dadurch natürlich auch nicht v- und hsync.
Hier der Code der signal-Entity:
in der Verhaltenssimulation sollte der Code funktionieren, ich sehe ihm
keinen Fehler an.
Allerdings zeigt dein Simulationsergebnis keine Verhaltenssimulation
sondern eine Timingsimulation, oder? Sonst würden die Signale ja bei der
Taktflanke umschalten, und nicht kreuz und quer verteilt.
Was für eine Taktfrequenz hast du denn in der Simu vorgegeben? Und hast
du per constraints geprüft, dass dein Design diese Frequenz schafft?
integer-subtype zum Zählen wäre sinnvoll. Aber der Isim läuft auch mit
dem Orginalcode des TO und zeigt (in der Verhaltenssimu) genau das
Verhalten, das man erwartet
Achim S. schrieb:> wenn CLK50 in der Simu mit ein paar GHz läuft, dann könnte es schon eine> Timing-Simu sein ;-)>> Die Zeitskala sieht man den Ausschnitt ja nicht an.
Hm, bei 5 GHz erwarte ich timing violations die in der Timing (aka
Post-P&R)- Simulation mit 'X' angezeigt werden sollten. Davon ist auch
nix zu sehen. Manchmal liegt es am falschen "Radix" im Waveform also
signed/unsigned/Hex statt integer - aber danach schaut es auch nicht aus
...
Ist das Design so eigentlich synthetisierbar? Wenn die Zuweisung, die
vcount oder hcount auf 0 springen lassen aktiv werden, sind die count <=
count + 1 Zuweisungen doch noch aktiv, die den jeweiligen Zähler
hochzählen lassen?
Hallo
Danke für die ganzen Antworten!
Also liegt es in dem Fall nicht an meinem Code, sondern am Simulator?
Ich habe es auch schon mit sehr niedrigen Frequenzen versucht (200kHz
oder so) und da war das gleiche Problem...
Ich habe mit Quartus II simuliert...
Verwendet ihr immer die Simulatoren, die in den IDEs (also Quartus II,
Xilinx, usw) oder externe Simulatoren? Wenn ja, welchen könntet ihr mir
empfehlen (wäre cool, wenn es den auch für Mac OS X geben würde).
lg
Samuel J. schrieb:> Also liegt es in dem Fall nicht an meinem Code, sondern am Simulator?
WAS simulierst du?
Machst du eine Verhaltenssimulation oder eine Timingsimulation?
Mit dem Vivado-Simulator funktioniert der Code auf jeden Fall auch
problemlos...
Lothar M. schrieb:> Auch der Aldec Simulator kann es, aber erst nachdem ein paar Zeilen> geändert wurden:> Beim ORiginalcode mosert er vollkommen zu Recht:
?? beim Orginalcode (Beitrag ganz oben) steht doch:
if(hcount > 799) then
hcount <= 0;
und das ist äquivalent zu
> if(hcount < 800) then
...
> else> hcount <= 0;
Da kann es die Fehlermeldung:
> # RUNTIME: Fatal Error: RUNTIME_0043 vgacontroller.vhd (29): Value 801> out of range (0 to 800).
eigentlich nicht geben.
? Welchen Orginalcode meinst du?
MfG,
Fpga K. schrieb:> ? Welchen Orginalcode meinst du?
Den vom ersten Post...
> ?? beim Orginalcode (Beitrag ganz oben) steht doch:> if(hcount > 799) then> hcount <= 0;
Richtig. Aber bei 799 wird der Zähler noch auf 800 erhöht. Und im
nächsten Takt wird er (vorübergehend!) auf 801 hochgezählt, um dann zwei
Zeilen weiter drunter auf 0 zurückgesetzt zu werden.
Und jetzt kommt das Unbestimmte, das die unterschiedliche Reaktion
begünstigt: ausserhalb des Prozesses hat der Zähler niemals mehr als
800. Aber er hätte beim "Einzelschrittbetrieb" innerhalb des Prozesses
kurz den Wert 801.
> und das ist äquivalent zu
Nein, genau das ist es nicht: im "Originalfall" wird unkonditioniert
weitergezählt. In meiner "korrigierten" Version wird erst abgefragt und
dann entweder gezählt oder zurückgesetzt.
Ich kann mit beiden Resultaten (Vivado und Aldec) leben, die
Beschreibung ist an dieser aber so unsauber, dass ich eher Richtung
Aldec tendiere...
Ganz am Rande: die 0..800 sind der übliche Gartenzaunpfosten-Fehler. Das
sind nämlich nicht wie gewünscht 800 Takte, sondern es sind 801 Takte...
Ich versteh nicht ganz wieso der counter auf 801 gesetzt wird.
Wenn ich schreibe:
1
if(hcount>799)then
2
hcount<=0;
3
else
4
hcount<=hcount+1;
5
endif;
Dann sollter er ja eigentlich bei 800 nicht mehr den Befehl in der
else-Bedingung ausführen, oder?
> Ganz am Rande: die 0..800 sind der übliche Gartenzaunpfosten-Fehler. Das> sind nämlich nicht wie gewünscht 800 Takte, sondern es sind 801 Takte...
Ja das ist mir auch schon aufgefallen... hab ich schon ausgebessert :)
> WAS simulierst du?> Machst du eine Verhaltenssimulation oder eine Timingsimulation?
Eine Verhaltenssimulation
lg
Samuel J. schrieb:> Ich versteh nicht ganz wieso der counter auf 801 gesetzt wird.> Wenn ich schreibe:>
1
>if(hcount>799)then
2
>hcount<=0;
3
>else
4
>hcount<=hcount+1;
5
>endif;
6
>
>> Dann sollter er ja eigentlich bei 800 nicht mehr den Befehl in der> else-Bedingung ausführen, oder?
Ja, das wird er auch in diesen code-schnipsel nicht. Allerdings hat es
im Orginal code-schnipsel kein else (wie ich erst jeztz bemerkte):
da steht:
hcount <= hcount + 1;
if(hcount > 799) then
hcount <= 0;
vcount <= vcount + 1;
end if;
Steht das signal hcount bei process-eintritt auf 799 wird es erst bei
process-ende auf den neuen Wert -800- gesetzt so dass der If-zweig nicht
abgearbeitet (da bis zum processende auf 799) wird, aber beim nächsten
process-eintritt auf 801 hochtickert.
Das ist halt ein Unterschied zwischen VHDL-signal und variable.
MfG,
Samuel J. schrieb:>> WAS simulierst du?>> Machst du eine Verhaltenssimulation oder eine Timingsimulation?> Eine Verhaltenssimulation
Dann ist es im Prinzip schnurzegal, ob du mit 5GHz oder 5µHz taktest.
Kurioses Ergebnis...
Fpga K. schrieb:> aber beim nächsten process-eintritt auf 801 hochtickert. Das ist halt> ein Unterschied zwischen VHDL-signal und variable.
Eigentlich nicht.
Denn der hcount ist ja ein Signal, das seinen neuen Wert erst am
Ende des Prozesses übernehmen sollte. Die Zehl 801 ist da also nur
vorübergehend vorhanden, man könnte es wie Vivado halten und
vorausschauend sagen: das ist ein theoretischer Wert, der wird dem
Signal nie zugewiesen, weil er vor dem Ende des Prozesses zurückgesetzt
wird.
Lothar M. schrieb:> man könnte es wie Vivado halten und> vorausschauend sagen: das ist ein theoretischer Wert, der wird dem> Signal nie zugewiesen, weil er vor dem Ende des Prozesses zurückgesetzt> wird.
Vielleicht liegt es auch daran, das bei vivado-isim defaultmäßig range
checking deaktiv ist. War jedenfalls bei mir der Fall.
MfG,
Fpga K. schrieb:> Vielleicht liegt es auch daran, das bei vivado-isim defaultmäßig range> checking deaktiv ist. War jedenfalls bei mir der Fall.
Ja helle Hölle, das ist tatsächlich so!
Und es wurde schon 2013 als kritischer Punkt angesehen:
https://forums.xilinx.com/t5/Simulation-and-Verification/Isim-natural-counter-exceeds-its-range/td-p/359383/page/3
Ein Simulation, die defaultmäßig nicht auf Einhaltung der Grenzen prüft
ist den Aufwand nicht wert.
Also frohgemut den Schalter mal eingeschaltet undmanglaubteskaum: der
läuft mit diesem Code hier
1
hcount<=hcount+1;
2
if(hcount>810)then
3
hcount<=0;
4
vcount<=vcount+1;
5
endif;
trotzdem munter ohne Meldung über die 800 raus. Das muss ich mir bei
Gelegenheit mal genauer ansehen. Und bis dahin nehme ich den
Aldec-Simulator...