Forum: FPGA, VHDL & Co. Active-HDL: wie bekomme ich die Waveform angezeigt


von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Mache gerade ein paar erste Schritte mit FPGAs. Habe mir ein 
Lattice-Demoboard beschafft. Das funktioniert soweit (wenngleich der 
Linux-Support leider lausig ist: Active-HDL gibt's gleich nur für 
Windows, und der Programmer, ein simpler FT2232, wird zwar von Linux 
erkannt, aber nicht vom Programming Tool). Die erste blinkende LED ist 
geschafft, nun möchte ich gern mal paar Schritte mehr machen und dabei 
auch was simulieren.

Das funktioniert soweit, wenn ich die Simulation mit dem "Simulation 
Wizard" im Lattice Radiant starte. Wenn ich dagegen im Aldec selbst 
nochmal was simuliere, bekomme ich im Waveform-Viewer irgendwie nichts 
mehr angezeigt. Die Simulation selbst ist gelaufen (mit "Run to" ... "1 
ms" – man sieht in den Meldungen, dass der Simulator die Millisekunde 
abgearbeitet hat).

Wie zum Geier™ bekomme ich die Waveforms da angezeigt?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Jörg W. schrieb:
> Wie zum Geier™ bekomme ich die Waveforms da angezeigt?
Kannst du mal die VHDL-Dateien von Testbench und Prüfling posten?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Ja, sicher.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite



Lesenswert?

1
use ieee.std_logic_unsigned.all;
2
use ieee.numeric_std.all;
Never ever both together!
Denn wenn du der std_logic_unsigned über die std_logic_arith ihre 
Arthmetikfunktionen mitgibst, dann bekommst du eigenartige Fehler mit 
doppelten Typdeklarationen bekommen:
# Error: COMP96_0272: toplevel.vhd : (10, 15): Ambiguous reference to 
type "UNSIGNED".
# Error: COMP96_0064: toplevel.vhd : (10, 15): Unknown type.
Vergiss die obsolete std_logic_math. Die numeric_std hat alles, was du 
brauchst:
http://www.lothar-miller.de/s9y/categories/16-Numeric_Std

Wenn du für interne Zähler integer mit passendem Range verwendest, wird 
das Ganze wesentlich leserlicher. Ich frage solche Zähler vor dem 
Hochzählen auf das Erreichen des Bereichsendes ab, dann muss ich keine 
Angst vor dem Überlauf haben:
1
if cnt <768 then
2
  cnt <= cnt+1;
3
else 
4
  cnt <= 0;
5
end if;

Ich nehme auch eher ungern solche verschachtelten if-Strukturen, sondern 
handle im Prozess ein (Ausgangs-)Signal nach dem anderen ab. Das ist 
kein Problem, denn während des gesamten Prozesses ändert keines der 
Signale seinen (Eingangs-)Wert. Wenn der Prozess mit linectr=768 
begonnen wird, dann ist während des gesamten Prozessdurchlaufs der Wert 
vom linectr = 768. Erst am Ende des Prozesses übernimmt dieses Signal 
den zuletzt zugewiesenen Wert. Deshalb bekommst du einen Überlauf auf 
769, obwohl du ja "sofort" auf 768 abgefragt hast.

Danach noch muss noch die Resetpolarität angepasst werden und dann tut 
sich schon was.

Beim Compilieren darauf achten, dass die Testbench als "Top-Level" 
gesetzt ist.
Du kannst "interne Signale" mit in die Waveform aufnehmen, wenn du in 
der Hierarchie ein wenig nach unten gehst.

: Bearbeitet durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

tnx, schau ich mir heute Abend an. Jetzt bin ich erstmal im Homeoffice. 
:)

von Markus F. (mfro)


Lesenswert?

nur kurz draufgeguckt:
1
    if reset = '1' then
2
        ...
3
    elsif rising_edge(clk) then
4
         ...
5
         if ctr >= 12_000_000 and reset /= '0' then

Im elsif-Zweig reset nochmal (verkehrt herum) abzufragen, scheint mir 
wenig zielführend.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Markus F. schrieb:
> Im elsif-Zweig reset nochmal (verkehrt herum) abzufragen, scheint mir
> wenig zielführend.
Wird hoffentlich wegoptimiert, weil redundant... ;-)

Wenn er nicht wegoptimiert wird, ist es noch schlimmer als es aussieht, 
denn durch diesen "invertierten" Reset im synchronen Pfad und den 
vorrangigen "normalen" Reset im asynchronen Pfad kann es sicher urige 
Effekte/Raceconditions geben. Da kann man nur hoffen, dass der Reset 
hübsch einsynchronisiert wurde. Sonst passiert sicher das hier:
http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html

Solche Reset-wurde-nicht-einsynchronisiert-Geschichten sind leicht daran 
zu erkennen, dass das Design manchmal nach dem Reset seltsame Dinge tut. 
Aber wenn es mal richtig gestartet ist, dann läuft es tagelang 
problemlos.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Lothar M. schrieb:

> Never ever both together!

Gut, verstanden.

Hätte mir wohl deine Seite zuerst durchlesen sollen, ist aber insgesamt 
ein bissel viel und für den Anfang etwas "querbeet". ;-)

> Wenn du für interne Zähler integer mit passendem Range verwendest, wird
> das Ganze wesentlich leserlicher. Ich frage solche Zähler vor dem
> Hochzählen auf das Erreichen des Bereichsendes ab, dann muss ich keine
> Angst vor dem Überlauf haben:

Ja, verstanden.

Dass die Signale innerhalb des Prozesses ihren Wert nicht ändern 
(sondern erst mit dem nächsten Takt), war mir im Prinzip klar, aber das 
hatte ich noch nicht so verinnerlicht. Da ist meine Denke noch zu sehr 
in klassischer Programmiersprache verhaftet.

> Ich nehme auch eher ungern solche verschachtelten if-Strukturen

Das war jetzt auch eher ein Anfang. Um eine etwas sinnvollere Anwendung 
als den LED-Blinker zu haben (der natürlich trotzdem noch schön im 
Sekundenrhythmus blinkt, damit man "was sieht" ;-), wollte ich mir mal 
ein BAS-Signal vornehmen. Damit man am Ende auch tatsächlich was sehen 
kann, ist da nun sowas wie eine Grautreppe. Da die 8 Graustufen 
gleichmäßig verteilt sind, kann man da vermutlich auch viel mehr durch 
den VHDL-Compiler rechnen lassen, statt sich die 8 Teile vorab mit der 
Hand auszurechnen.

Es kommt am DAC auch sowas wie eine Treppe raus, aber sie entspricht 
nicht den Erwartungen (und jetzt auch nicht der Simulation), insofern 
muss ich wohl meine Pin-Zuweisungen nochmal verifizieren.

> Beim Compilieren darauf achten, dass die Testbench als "Top-Level"
> gesetzt ist.

Das hatte ich schon so (hat ja auch nur so Sinn, wenn man drüber 
nachdenkt).

Insgesamt habe die Funktionsweise von Simulator und Waveform-Display 
irgendwie ganz anders erwartet. Ich dachte, man simuliert da was, und 
danach kann man sich die Signale auswählen, die man angezeigt bekommen 
möchte. Bzw., wenn man sie früher schon mal gewählt hatte, werden sie 
bei einer neuen Simulation automatisch wieder da aufgenommen.

Wie ich nun tatsächlich etwas sehe: Toplevel festlegen, "Initialize 
simulation". Ab da sind die Signale links unten (Structure view) nicht 
mehr "Unavailable", und man kann sie in die Waveform-Anzeige ziehen. 
Danach dann "Run to". Etwas verwirrend für mich, dass man während der 
Simulation rein gar nichts sieht. Ich hätte erwartet, dass die 
Waveform-Anzeige zumindest gelegentlich mal aktualisiert wird, oder man 
sonst irgendwie in der Console eine Fortschrittsanzeige in Form einer 
mitlaufenden Simulationszeit hat.

So sehe ich nun zumindest überhaupt was, danke! Habe auch schon einen 
Bug entdeckt: nach der Simulation von 1,01 s ging der LED-Ausgang auf 
"U", weil der interne ledstate zwar getoggelt wird, aber nie 
initialisiert worden ist. Klar, in der Realität blinkt die LED natürlich 
:), denn das Flipflop kann nicht "U" sein.

Markus F. schrieb:
> Im elsif-Zweig reset nochmal (verkehrt herum) abzufragen, scheint mir
> wenig zielführend.

Stimmt, danke. War bisschen ein Denkfehler.

: Bearbeitet durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

OK, nachdem es sich nun simulieren lässt, stimmt auch die Ausgabe. ;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Eine Frage habe ich nun doch noch speziell zum Simulator: wenn ich bei 
oben gezeigtem Bild "Export Waveform" als VCD mache und "All signals" 
wähle – warum bekomme ich dann immer nur dut:newline im VCD-File?

Wollte mir das gern mal im GTKwave ansehen …

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Ah falsch verstanden. waveform_tb enthält LED, clk und reset im Export, 
dut ist dagegen ein Submodule davon und enthält newline.

Aber: "waveout" bekomme ich irgendwie nicht in den Export rein.

So, nun erstmal wieder Homeoffice …

: Bearbeitet durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Warum da dies oder jenes an Signalen manchmal im VCD drin ist und 
manchmal nicht, bleibt mir vorerst ein Rätsel. Vielleicht gucke ich ja 
demnächst nochmal, ob ich das auch alles in GVHDL simuliert bekomme. 
Allein sowas ist doch wiedermal einfach nur lästig:
1
# KERNEL: Warning: You are using the Active-HDL Lattice Edition. The performance of simulation is running at a reduced rate.
2
# KERNEL: Warning: Contact Aldec for available upgrade options - sales@aldec.com.

Anyway, habe mit der Generierung eines rudimentären Fernsehsignals 
bisschen weiter gebastelt. Jetzt ist da ganz viel integer drin, Vektoren 
werden dann erst bei der Ausgabe draus gemacht. Simulation sieht auch 
schlüssig aus.

Weitere Kritik willkommen. ;-)

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

Jörg W. schrieb:
> Allein sowas ist doch wiedermal einfach nur lästig:
> # KERNEL: Warning: You are using the Active-HDL Lattice Edition. The
> performance of simulation is running at a reduced rate.
Das Problem gibt es bei GHDL nicht. Dafür ist es nicht ganz so bunt ;-)

> Anyway, habe mit der Generierung eines rudimentären Fernsehsignals
> bisschen weiter gebastelt. Jetzt ist da ganz viel integer drin, Vektoren
> werden dann erst bei der Ausgabe draus gemacht.
Ja, solange die integer eingeschrängte Bereiche haben ist das o.k.
Ich empfehle auch, gerade in der Anfangsphase, mal zu schauen, was der 
Synthesizer vom Code verstanden hat. Bei Diamond geht das mit dem 
Netlist Analyzer.

> Simulation sieht auch schlüssig aus.
Und was macht die Hardware daus? Synchronisiert sich der Bildschirm 
schon?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Duke Scarring schrieb:

> Das Problem gibt es bei GHDL nicht. Dafür ist es nicht ganz so bunt ;-)

Das allein wäre Grund genug, sich den mal anzusehen. :)

Allerdings habe mit gvhdl bislang noch kein Simulationsergebnis zustande 
bekommen für die gleiche Konfiguration.
1
j@wega 332% gvhdl tb.vhdl toplevel.vhdl --libieee
2
gvhdl: FreeHDL root path is '/usr'.
3
gvhdl: executing '/usr/bin/freehdl-v2cc -m tb._main_.cc -L /usr/share/freehdl/lib   -o tb.cc tb.vhdl'
4
gvhdl:
5
gvhdl: ================================
6
gvhdl: Compiling 'tb.cc'...
7
gvhdl: ================================
8
gvhdl: x86_64-linux-gnu-g++  -I /usr/include -c tb.cc
9
gvhdl: executing '/usr/bin/freehdl-v2cc -m tb._main_.cc -L /usr/share/freehdl/lib   -o toplevel.cc toplevel.vhdl'
10
gvhdl:
11
gvhdl: ================================
12
gvhdl: Compiling 'toplevel.cc'...
13
gvhdl: ================================
14
gvhdl: x86_64-linux-gnu-g++  -I /usr/include -c toplevel.cc
15
gvhdl:
16
gvhdl: ================================
17
gvhdl: Compiling simulator main file 'tb._main_.cc'...
18
gvhdl: ================================
19
gvhdl: x86_64-linux-gnu-g++  -I /usr/include -c tb._main_.cc
20
gvhdl: Linking simulator 'tb'...
21
gvhdl: libtool --mode=link --tag CXX x86_64-linux-gnu-g++  tb._main_.o  tb.o toplevel.o -lm /usr/lib/libfreehdl-kernel.la /usr/lib/libfreehdl-std.la /usr/lib/freehdl/libieee.la -o tb
22
linker: libtool: link: x86_64-linux-gnu-g++ tb._main_.o tb.o toplevel.o -o tb  -lm /usr/lib/libfreehdl-kernel.so /usr/lib/libfreehdl-std.so /usr/lib/freehdl/libieee.so -Wl,-rpath -Wl,/usr/lib/freehdl -Wl,-rpath -Wl,/usr/lib/freehdl
23
gvhdl: ================================
24
gvhdl: Simulator 'tb' created.
25
gvhdl: ================================
26
j@wega 333% ./tb -cmd 'd; r 1 ms; d; q'
27
Available commands:
28
  h          : prints list of available commands
29
  c <number> : execute cycles = execute <number> simulation cycles
30
  n          : next = execute next simulation cycle
31
  q          : quit = quit simulation
32
  r <time>   : run = execute simulation for <time>
33
  d          : dump = dump signals
34
  doff       : dump off = stop dumping signals
35
  don        : dump on = continue dumping signals
36
  s          : show = show signal values
37
  dv         : dump var  = dump a signal from the signal lists
38
  ds         : dump show  = shows the list of dumped signals
39
  nds        : number  show  = shows the number  of dumped signals
40
  wdd        : write binary design info
41
  wddl       : write design info using a CDFG style syntax
42
  db_view    : print kernel database
43
  dc [-f <filename>] [-t <timescale> <time unit>] [-cfg <translation file>] [-q] :control waveform dumping
44
Simulation time = 0 fs + 0d
45
> > Run simulation for which time span? 
46
Simulating model to time 1 ms
47
signal :wave changed
48
Simulation time = 0 fs + 1d
49
50
1 processes were executed.
51
0 transaction were created.
52
> > j@wega 334% 
53
j@wega 334% cat wa
54
wave.dmp      waveform.pdc  
55
j@wega 334% cat wave.dmp 
56
$date
57
     Aug  4 2015  00:39:09
58
$end
59
$version
60
    FREEHDL 0.0.8
61
$end
62
$timescale
63
    1 ns
64
$end
65
$scope module behavioral $end
66
$var   integer 24 ! ctr $end
67
$var   trireg 1 " hsync $end
68
$var   trireg 1 # in_hsync $end
69
$var   trireg 1 $ in_vsync $end
70
$var   trireg 1 % ledstate $end
71
$var   integer 9 & linectr $end
72
$var   trireg 1 ' newline $end
73
$var   integer 10 ( pixelctr $end
74
$var   trireg 1 ) vsync $end
75
$var   integer 8 * waveout $end
76
$upscope $end
77
$var   trireg 1 + clk $end
78
$var   trireg 1 , led $end
79
$var   trireg 1 - reset $end
80
$var   reg 8 . wave[7:0] $end
81
$enddefinitions $end
82
#0
83
$dumpvars
84
b0 !
85
0"
86
0#
87
0$
88
X%
89
b0 &
90
X'
91
b0 (
92
0)
93
b0 *
94
X+
95
X,
96
X-
97
bXXXXXXXX .
98
$end
99
#0
100
b0 .
101
#0
102
$dumpvars
103
b0 !
104
0"
105
0#
106
0$
107
X%
108
b0 &
109
X'
110
b0 (
111
0)
112
b0 *
113
X+
114
X,
115
X-
116
b0 .
117
$end

Ist irgendwie für 1 ms Simulationszeit nicht so richtig viel, was da 
drin steht …

> Ich empfehle auch, gerade in der Anfangsphase, mal zu schauen, was der
> Synthesizer vom Code verstanden hat. Bei Diamond geht das mit dem
> Netlist Analyzer.

Ja, habe ich im Blick, hatte mir Lothar schon mal empfohlen.

>> Simulation sieht auch schlüssig aus.
> Und was macht die Hardware daus? Synchronisiert sich der Bildschirm
> schon?

Bin ich noch nicht dazu gekommen, wird heute abend.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Jörg W. schrieb:
> Bin ich noch nicht dazu gekommen, wird heute abend.

Hmm, irgendwie habe ich wohl den Programmer auf dem Board gekillt. :-(
1
Board with FTDI USB Host Chip detected.
2
3
4
Frequency setting= 15000000 Hz
5
Check configuration setup: Start.
6
Check configuration setup: Successful (Ignored JTAG Connection Checking).
7
Device1 iCE40UP5K: N25Q032A: Erase,Program,Verify
8
9
Frequency setting= 29940 Hz
10
Initializing...
11
IDCode Checking...
12
Function:CHECK_ID
13
Data Expected: h16  Actual: hFF
14
Operation: unsuccessful.
15
Programming XCF Contents... Failed.

Unter Windows das gleiche wie unter Linux.

Das FPGA selbst lässt sich mit der letzten im Flash hinterlegten 
Konfiguration noch konfigurieren, daran scheint es nicht zu liegen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hmm, jetzt geht's wieder. Seltsam.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Duke Scarring schrieb:
> Und was macht die Hardware daus? Synchronisiert sich der Bildschirm
> schon?

Ich denke, dass man das durchgehen lassen kann. ;-)

Musste erst noch einen Impedanzwandler hinter meinen recht hochohmigen 
R-2R-DAC setzen, um damit einen Video-Eingang anzusteuern.

(Der schräge Streifen ist ein Artefakt der Handy-Belichtung.)

: Bearbeitet durch Moderator
von Gustl B. (-gb-)


Lesenswert?

Lob und Anerkennung! Ist das Pal? Sieht gut aus!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Gustl B. schrieb:
> Ist das Pal?

Reines CCIR. Der Gucki ist ohnehin nur S/W.

Der Aufwand für PAL dürfte sich nicht lohnen. Wenn, würde man ja eher 
über VGA oder SCART an so eine Farbglotze einspeisen und RGB separat 
führen.

Ist im Moment auch erstmal einfach 312 Zeilen mit 50 Hz, ohne 
Zeilensprung. Das ist einfacher zu implementieren, so hat auch die 
Videoaufbereitung meines ersten Eigenbaucomputers vor 35 Jahren 
gearbeitet. Man könnte natürlich noch Zeilensprung implementieren (in 
realer Hardware wäre das Aufwand gewesen, im FPGA sind es nur ein paar 
Zeilen mehr), aber da stellt sich die Frage der Anwendung. Zeilensprung 
bringt flimmernde horizontale Linien, lohnt daher eigentlich wirklich 
nur für echte Bilder, nicht für Strich- oder Pixelgrafiken.

Eine Schwarzwert-Klemmung werde ich aber noch probieren. Wenn man das 
Signal nur wechselspannungsmäßig aufbereitet, hat man das Problem, dass 
bei Bildern mit viel hellem Anteil (wie hier) die 0 V für schwarz nicht 
erreicht werden. DC-Kopplung würde eine negative Versorgung für den 
Ausgangsverstärker brauchen. Wenn ich aber den Ausgangskondensator 
während der Austastlücken mit einem Transistor entlade, sollte sich das 
verbessern lassen. Ich weiß ja im FPGA, wenn es wirklich 0 V sein 
sollen, und kann in dieser Zeit ein Steuersignal für einen Transistor 
separat ausgeben.

: Bearbeitet durch Moderator
von Gustl B. (-gb-)


Lesenswert?

Jörg W. schrieb:
> DC-Kopplung würde eine negative Versorgung für den
> Ausgangsverstärker brauchen. Wenn ich aber den Ausgangskondensator
> während der Austastlücken mit einem Transistor entlade, sollte sich das
> verbessern lassen. Ich weiß ja im FPGA, wenn es wirklich 0 V sein
> sollen, und kann in dieser Zeit ein Steuersignal für einen Transistor
> separat ausgeben.

Kann man bestimmt machen. Aber braucht man wirklich diesen Verstärker? 
VGA habe ich nur mit einem R2R DAC gemacht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Gustl B. schrieb:
> Aber braucht man wirklich diesen Verstärker?

Ich habe nur 50-kΩ-Netzwerke für den R-2R-DAC gerade da. Da sah man 
selbst mit der Oszi-Tastspitze schon arg verschliffene Flanken. Ich 
denke nicht, dass das ohne einen Impedanzwandler Sinn gehabt hätte.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.