mikrocontroller.net

Forum: FPGA, VHDL & Co. VGA Versuch - Problem beim Simulieren


Autor: Samuel J. (capstrovor)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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:
library IEEE;
use ieee.std_logic_1164.all;

entity signals is
port
(
  clk: in std_logic;
  vsync: out std_logic;
  hsync: out std_logic;
  drawEN: out std_logic
);
end entity;

architecture behav of signals is
type count is range 0 to 800;
signal hcount: count:=0;
signal vcount: count:=0;
begin
  process(clk) begin
    if(rising_edge(clk)) then
      hcount <= hcount + 1;
      if(hcount > 799) then
        hcount <= 0;
        vcount <= vcount + 1;
      end if;
      if(vcount > 520) then
        vcount <= 0;
      end if;
      
      if(hcount >= 0 AND hcount < 96) then
        hsync <= '0';
      else
        hsync <= '1';
      end if;
      
      if(vcount >= 0 AND vcount < 2) then
        vsync <= '0';
      else
        vsync <= '1';
      end if;
      
      if(hcount > 143 AND hcount < 783 AND vcount > 31 AND vcount < 510) then
        drawEN <= '1';
      else
        drawEN <= '0';
      end if;
    end if;
  end process;
end behav;

Und hier noch die Top-Level entity:
library IEEE;
use ieee.std_logic_1164.all;

entity vgaTop is
port
(
  clk50: in std_logic;
  hsync: out std_logic;
  vsync: out std_logic;
  r: out std_logic_vector(3 downto 0);
  g: out std_logic_vector(3 downto 0);
  b: out std_logic_vector(3 downto 0)
);
end entity;

architecture behav of vgaTop is
  Component signals
    Port(
      clk: in std_logic;
      vsync: out std_logic;
      hsync: out std_logic;
      drawEN: out std_logic);
  end Component;
  
  signal drawEN: std_logic;
begin
  signals1: signals Port Map(clk50, vsync, hsync, drawEN);
end behav;

im Anhang noch das Bild der Simulation.

lg

Autor: Achim S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probiers mal mit einem Integer-Subtype zum Zählen statt des 
selbstdefinierten count-Typs...

Autor: Fpga Kuechle (fpgakuechle) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Statt
type count is range 0 to 800;

besser:
subtype count is integer range 0 to 800;

: Bearbeitet durch User
Autor: Achim S. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Fpga Kuechle (fpgakuechle) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja der Simulator verhält sich irgendwie besoffen, das schaut mir auch 
nicht nach Timing-simu aus.

MfG,

Autor: Achim S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Fpga Kuechle (fpgakuechle) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 
...

Autor: Joschua C. (blauerpinguin)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Prozess "gewinnt" die letzte Zuweisung an ein Signal...

Autor: Joschua C. (blauerpinguin)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieder was gelernt, danke

Autor: Samuel J. (capstrovor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Quartus verwendet doch eh ModelSim von Mentor...

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Auch der Aldec Simulator kann es, aber erst nachdem ein paar Zeilen 
geändert wurden:
    :
    :
    if(rising_edge(clk)) then
      if(hcount < 800) then
        hcount <= hcount + 1;
      else
        hcount <= 0;
        vcount <= vcount + 1;
      end if;
Beim ORiginalcode mosert er vollkommen zu Recht:
# RUNTIME: Fatal Error: RUNTIME_0043 vgacontroller.vhd (29): Value 801 out of range (0 to 800).
# KERNEL: Time: 16010 ns,  Iteration: 0,  Instance: /tb_topVGA/tvga/signals1,  Process: line__20.
# KERNEL: Stopped at time 16010 ns + 0.
# Error: Fatal error occurred during simulation.
Denn hier wird der hcount vor dem Zurücksetzen auf 801 hochgezählt und 
verlässt so seinen Wertebereich...

: Bearbeitet durch Moderator
Autor: Fpga Kuechle (fpgakuechle) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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,

: Bearbeitet durch User
Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

: Bearbeitet durch Moderator
Autor: Samuel J. (capstrovor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich versteh nicht ganz wieso der counter auf 801 gesetzt wird.
Wenn ich schreibe:
if(hcount > 799) then
   hcount <= 0;
else
   hcount <= hcount + 1;
end if;

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

Autor: Fpga Kuechle (fpgakuechle) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel J. schrieb:
> Ich versteh nicht ganz wieso der counter auf 801 gesetzt wird.
> Wenn ich schreibe:
>
> if(hcount > 799) then
>    hcount <= 0;
> else
>    hcount <= hcount + 1;
> end if;
> 
>
> 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,

: Bearbeitet durch User
Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Fpga Kuechle (fpgakuechle) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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,

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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-Verifi...
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
      hcount <= hcount + 1;
      if(hcount > 810) then
        hcount <= 0;
        vcount <= vcount + 1;
      end if;
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...

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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