VGA Versuch - Problem beim Simulieren

#4513528
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:
1
library IEEE;
2
use ieee.std_logic_1164.all;
3

4
entity signals is
5
port
6
(
7
  clk: in std_logic;
8
  vsync: out std_logic;
9
  hsync: out std_logic;
10
  drawEN: out std_logic
11
);
12
end entity;
13

14
architecture behav of signals is
15
type count is range 0 to 800;
16
signal hcount: count:=0;
17
signal vcount: count:=0;
18
begin
19
  process(clk) begin
20
    if(rising_edge(clk)) then
21
      hcount <= hcount + 1;
22
      if(hcount > 799) then
23
        hcount <= 0;
24
        vcount <= vcount + 1;
25
      end if;
26
      if(vcount > 520) then
27
        vcount <= 0;
28
      end if;
29
      
30
      if(hcount >= 0 AND hcount < 96) then
31
        hsync <= '0';
32
      else
33
        hsync <= '1';
34
      end if;
35
      
36
      if(vcount >= 0 AND vcount < 2) then
37
        vsync <= '0';
38
      else
39
        vsync <= '1';
40
      end if;
41
      
42
      if(hcount > 143 AND hcount < 783 AND vcount > 31 AND vcount < 510) then
43
        drawEN <= '1';
44
      else
45
        drawEN <= '0';
46
      end if;
47
    end if;
48
  end process;
49
end behav;

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

4
entity vgaTop is
5
port
6
(
7
  clk50: in std_logic;
8
  hsync: out std_logic;
9
  vsync: out std_logic;
10
  r: out std_logic_vector(3 downto 0);
11
  g: out std_logic_vector(3 downto 0);
12
  b: out std_logic_vector(3 downto 0)
13
);
14
end entity;
15

16
architecture behav of vgaTop is
17
  Component signals
18
    Port(
19
      clk: in std_logic;
20
      vsync: out std_logic;
21
      hsync: out std_logic;
22
      drawEN: out std_logic);
23
  end Component;
24
  
25
  signal drawEN: std_logic;
26
begin
27
  signals1: signals Port Map(clk50, vsync, hsync, drawEN);
28
end behav;

im Anhang noch das Bild der Simulation.

lg
Angehängte Dateien:
Gast #4513805
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?
Gast #4513871
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 
...
Gast #4513890
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?
#4514534
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
Moderator (Firma: Titel) Persönliche Seite #4514716
Lesenswert?

Auch der Aldec Simulator kann es, aber erst nachdem ein paar Zeilen 
geändert wurden:
1
    :
2
    :
3
    if(rising_edge(clk)) then
4
      if(hcount < 800) then
5
        hcount <= hcount + 1;
6
      else
7
        hcount <= 0;
8
        vcount <= vcount + 1;
9
      end if;
Beim ORiginalcode mosert er vollkommen zu Recht:
1
# RUNTIME: Fatal Error: RUNTIME_0043 vgacontroller.vhd (29): Value 801 out of range (0 to 800).
2
# KERNEL: Time: 16010 ns,  Iteration: 0,  Instance: /tb_topVGA/tvga/signals1,  Process: line__20.
3
# KERNEL: Stopped at time 16010 ns + 0.
4
# 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...
Angehängte Dateien:
Gast #4514773
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,
Moderator (Firma: Titel) Persönliche Seite #4514831
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...
#4514875
Lesenswert?

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
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
Gast #4514917
Lesenswert?

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
> end if;
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,
Moderator (Firma: Titel) Persönliche Seite #4514981
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.
Gast #4515028
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,
Moderator (Firma: Titel) Persönliche Seite #4515090
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-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
      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...
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