Hallo,
bisher habe ich in VHDL einen anliegenden Takt in einer VHDL-Test Bench
in jeweils einem Prozess erzeugt.
1
tb:PROCESS
2
BEGIN
3
BTN0<='0';
4
waitfor10ms;
5
BTN0<='1';
6
waitfor10ms;
7
ENDPROCESStb;
8
9
CLOCK:PROCESS
10
BEGIN
11
CLK<='0';
12
waitfor20ns;
13
CLK<='1';
14
waitfor20ns;
15
END
Das funktioniert auch soweit ganz gut.
Dann zeigte uns unser Dozent einen eleganteren Weg als über Prozesse.
Leider nicht aufgeschrieben. So musste ich es aus dem Kopf aufschreiben.
In etwa so:
1
BTN0<='0'after10mswhenBTN0='1'elseBTN0<='1';
2
CLK<='0'after20mswhenCLK='1'elseCLK<='1';
Ist viel eleganter und man braucht nur einen Zahlenwert ändern, wenn man
nicht gerade mit Pulsen arbeitet.
Jedoch hat es einen kleinen Nachteil, es funktioniert nicht. ISE steigt
mit einem für ISE typischen nichtssagenden Fehler aus:
1
found '0' definitions of operator "<=", cannot determaine exact overloaded matching definition for "<="
Da stellen sich mir ein paar fragen:
1. Watt???
2. VHDL ist objektorientiert?
3. Man kann Operatoren überladen?
4. Wie?
5. Wieso?
6. Warum schreibt ISE für eine Anzahl 0 die Zahl in Hochkommata? Also
warum nicht einfach nur:
1
found 0 (oder no) definitions of
7. Was zum Teufel hat das mit den Zeilen zutun?
Wie die Zeilen korrekt aussehen müssten konnte ich im gesamten Internet
nicht finden. Keine Ahnung warum. Ist wohl doch nicht so typisch.
Das einzige was ich fand ist unter
[Titel]http://www.mikrocontroller.net/articles/VHDL_Testbench folgende
Zeile:
1
clk<=notclkafter20ns;-- 25 MHz Taktfrequenz
also
1
BTN0<=notBTN0after10ms;
2
CLK<=notCLKafter20ns;
Das geht zwar, aber ISim führt dann die Simulation nicht durch. Also,
wird gestartet, im Wave-Fenster oder wie sich das schimpft passiert
nichts und ich kann auch nicht "play" drücken.
VHDL ist schwer genug. Warum muss die IDE nur so grausam sein?
Naja, wie ich euch kenne, wisst Ihr mehr als das Internet, Google und
mein Dozent zusammen. ;)
War bisher immer so.
Überraschenderweise steht darüber auch nichts in VHDL-Synthese: Entwurf
digitaler Schaltungen und Systeme ISBN 3486589873 . Was mich schon sehr
überrascht.
Ich bedanke mich im voraus.
Gruß
Fabian
Wenn man den Syntax-Fehler weglässt, wirds kompiliert. Hättest es dir
vielleicht doch aufschreiben sollen:
1
CLK<='0'after20nswhenCLK='1'else'1';
Aber nur eine Zahl austauschen geht auch so, wie ISE das bei den
automatisch generierten Testbenches macht:
1
-- Clock period definitions
2
constantCLK_period:time:=10ns;
3
4
CLK_process:process
5
begin
6
CLK<='0';
7
waitforCLK_period/2;
8
CLK<='1';
9
waitforCLK_period/2;
10
endprocess;
Natürlich kann man Operatoren überladen, wenn man genau weiß, was man
tut. In verschiedenen Libs kann + oder - oder was auch immer schon mal
anders definiert sein. Das hat aber nichts mit OO zu tun, vergiss mal
ganz schnell die Denkweise hinter C++ oder sonstiger sequenzieller
Programmierung, wenn du VHDL schreibst. VHDL ist kein echtes
Programmieren, sondern ein Beschreiben von Hardware. Dafür steht das D
in VHDL.
1
clk<=notclkafter20ns;
Funktioniert übrigens auch, aber nur, wenn bei der Signal-Deklaration
das Signal auch intialisiert wird. Mein ISim schluckt das einwandfrei.
Da muss irgendwo anders ein Fehler liegen bei dir. Vielleicht das wait;
im Stimulus-Prozess vergessen?
Dir fehlen da offenbar noch entscheidende Grundlagen. Bevor du über die
ISE meckerst (die schon wirklich etwas gewöhnungsbedürftig ist),
solltest du die Syntax von VHDL lernen und dir die Grundlagen anlesen.
Danke für die schnelle Antwort.
Ich bin jetzt ein Stück weiter.
Ich weiß aber gar nicht, wo ich anfangen soll.
Erst einmal, was soll man von VHDL halten? Erst, so scheint es, machen
die alles richtig und setzten auf Pascal und nicht wie sonst üblich
eines der Millionen Basic-Derivate. Bin da etwas nostalgisch, da ich
damit das Programmieren gelernt habe. Dann aber wird es inkonsistent.
Signal-Definitionen, also die Zuweisung, wird mit dem Operator "<="
gemacht, jedoch nicht, bei der Deklaration. Dann wird der Operator für
die Variablen-Deklaration ":=" verwendet. Wieso?
Das selbe ist mir bei dem when-else-Statement aufgefallen. Beim
sequenziellem Pendant if-then-else-Statement sagt man ja auch nicht
1
then<Anweisung1>if<Bedingung>else<Anweisung2>;
. Hier aber macht man das. Wozu diese Inkonsistenz?
.
1
else '1'
ist ja wohl der blanke Hohn. Der Teil, den ich nicht ganz ohne Grund
falsch gemacht habe. Wozu diese Syntax? Das erinnert mich an meine
ersten Programmiertage, als ich das erste Mal versuchte auf zwei
Bedingung zu prüfen. In etwa so:
1
if(x==0||5);
.
Ich meine, was ist, wenn ich im parallelen Teil, also in der
Architecture sagen möchte, „wenn eine Bedingung erfüllt ist, dann soll
ein Signal gesetzt werden, wenn nicht, soll ein anderes Signal gesetzt
werden”? Dafür brauche ich zwei whens.
Unlesbar, erst den mittleren, dann den linken und dann den rechten Part
der Anweisung lesen zu müssen.
Nagut, zurück zum Thema. Mit der richtigen Syntax lässt sich die
Simulation starten, aber mit dem gleichen Problem wie mit der anderen
Anweisung.
Wie man in dem Bild sieht, habe ich die Eingänge initialisiert. Dennoch
mag der Simulator nicht arbeiten. Erzeuge ich den Takt in Prozessen, wie
oben oder von Dir gezeigt, funktioniert es. Ohne [vhdl]WAIT;[vhdl].
Macht ja auch kein Sinn. Ein Prozess wird ja auch wieder von neuem
gestartet wenn er durchlaufen wurde. Ist aber egal, die Versionen ohne
Prozessen funktionieren nicht, weder mit noch ohne wait;.
Weißt Du noch einen Tipp?
Über den Sinn und Unsinn der Syntax braucht man nicht zu diskutieren,
die Sprache gibts schon ewig, die Grundkonstrukte wird nun keiner mehr
ändern. VHDL ist halt geschwätzig. Kannst ja Verilog nehmen.
In der TB muss schon mindestens ein Prozess sein, sonst passiert nix.
Daher macht ISE ja beim Erstellen der Testbench automatisch den stim
Process der nur ein wait; enthält.
Wie gesagt, egal ob mit oder ohne WAIT; im Prozess, es wird nichts
simuliert.
ISE kommt mir vor wie Windows: Geht nix, hilft nur Neustart, geht gar
nix hilft nur neu installieren, also in diesem Fall, dass komplette
Projekt händisch neu bauen. Und die Fehlermeldungen sind ähnlich clever.
Ziemlich mühsam das ganze.
Seltsam, bis auf ein paar bekannte Fehler geht ISE und ISim bei mir sehr
gut. Ich arbeite täglich 8 Stunden damit. Klar, bissl umständlich, aber
das sind die anderen Tools von Altera und Lattice auch. Alle erfordern
Einarbeitung. Lade mal dein komplette Projekt hoch, dann schaun wir mal,
was da ist. Alles andere ist Rätsel raten.
Supi! Ich danke Dir!
Ich benutze im übrigen die aktuelle Version.
ISE WebPack 13.3.
Es handelt sich im wesentlichen um 2 Projekte. Beides sind BCD-Counter.
Eines wird nur mit dem 50MHz-Takt getaktet, dort wird der Takt erst auf
5Hz runtergeteilt und dann erst zum zählen verwendet. Bei dessen
Simulation muss das ganze für gut 2 Sekunden durchsimuliert werden.
Das zweite wird mit einem Taster getaktet, bei dem der Takt nur zum
entprellen genutzt wird. Hierbei muss der Button immer für mindestens
1ms gedrückt, bzw. losgelassen werden, da sonst ein Wechseln nicht
erkannt wird.
Ich bin mal gespannt. Vielen Dank.
Abgesehen von den massiven Anfängerfehlern und der Sinnlosigkeit einer
Simulation über Sekunden (was mit 5 Hz Takt funktioniert, funktioniert
in der Simulation genauso mit 50MHz) musst du die einzeilige
Takterzeugung natürlich für beide Flanken beschreiben:
1
BTN0<='1'after10mswhenBTN0='0'else'0'after10ms;
2
CLK<='1'after10nswhenCLK='0'else'0'after10ns;
Außerdem hast du nur leere Prozesse drin gehabt, kein Wunder, dass die
Simulation nicht startet. Kein prozess ist was anderes als ein leerer
Prozess. Ich hab doch mehrfach geschrieben, dass da mindestens ein
Prozess mit einem wait; drin sein muss.
1
tb:PROCESS
2
BEGIN
3
-- BTN0 <= '0';
4
-- Wait for 2 ms;
5
-- BTN0 <= '1';
6
-- Wait for 2 ms;
7
WAIT;
8
ENDPROCESS;
Dann klappts auch mit der Simulation.
Gewöhn dir am besten ganz schnell den Schematic-Mist wieder ab. Die
Testbensch musst du eh in VHDL/Verilog schreiben, also kannst du das
bisschen da auch ordentlich beschreiben. Und beachte die goldenen Regeln
für Anfänger von Lothar Miller.
Christian R. schrieb:> Außerdem hast du nur leere Prozesse drin gehabt, kein Wunder, dass die> Simulation nicht startet. Kein prozess ist was anderes als ein leerer> Prozess. Ich hab doch mehrfach geschrieben, dass da mindestens ein> Prozess mit einem wait; drin sein muss.
Und ich habe auch mehr als einmal geschrieben, dass das WAIT; keinen
Einfluss auf die Simulation hatte.
Zweites kann ich an der Aufgabenstellung leider nichts ändern. Wenn
Schematic gefordert ist, dann mache ich es in Schematic.
Aber danke erstmal, ich schaue es mir an.
Kommando zurück!
Im 2. Prozess hatte ich immer vergessen das WAIT;-Statement
hinzuzufügen. Ich hatte nur den tb:-Prozess betrachtet.
Jetzt geht es, wenn in ALLEN Prozessen das WAIT; enthalten ist, Naja.
Ich bedanke mich auf jeden Fall.
Einen schönen Sonntag noch.
Na dann ist ja gut. Hättest du den gesamten Prozess samt Begin und end
auskommentiert, wäre es auch gegangen. Ist halt blöd, dass ISim da keine
Meldung bringt, ist aber auch kein wirtklich ernst zu nehmender
Simulator. Modelsim bringt da eine Fehlermeldung.
Gut, wenn das eine Aufgabenstellung ist, dann muss es halt so sein.
Viel Erfolg noch damit. An sich scheint es ja zu kontionieren.
Der kann keine Analog-Darstellung von Signalen, was mir besonders
wichtig ist, außerdem ist die Bedienung suboptimal. Kann man den
eigentlich mittlerweile über TCL steuern?
Fabian Hoemcke schrieb:> Jetzt geht es, wenn in ALLEN Prozessen das WAIT; enthalten ist, Naja.
Naja, das ist VHDL...
Ein Prozess hat entweder (mindestens) 1 wait oder eine Sensitivliste.
Fabian Hoemcke schrieb:> Erst, so scheint es, machen die alles richtig und setzten auf Pascal> und nicht wie sonst üblich eines der Millionen Basic-Derivate.
Diese Denkweise ist (wie Christian schon angemerkt hat) grundlegend
falsch. VHDL ist keine Programmiersprache. Es ist eine
Hardwarebeschreibungssprache. Und dann ist das wie wenn du sagst: ein
Schiff schwimmt einfach anders als ein LKW. Das muß so sein. Dafür ist
ein Schiff ausgelegt, ein LKW dagegen nicht.
Fabian Hoemcke schrieb:> 1. Watt???
= Spannung mal Strom.
> 2. VHDL ist objektorientiert?
Ja, denn die ganzen Datentypen sind Objekte und du kannst deine eigenen
Rechenoperationen für diese Objekte definieren.
> 3. Man kann Operatoren überladen?
Sieh dir einfach mal den Quelltext für dein numeric_std an:
http://www.csee.umbc.edu/portal/help/VHDL/packages/numeric_std.vhd
Da siehst du, dass für jede Manipulation zweier Objekte eine Funktion
definiert ist (sein muß).
> 4. Wie?
Schreib deine eigene Berechnungsfunktion.
> 5. Wieso?
Damit du eigene neue Objekte anlegen und miteinender bzw. mit
existierenden Objekten verrechnen kannst.
> 6. Warum schreibt ISE für eine Anzahl 0 die Zahl in Hochkommata?
Warum wird in C ein einzelnes Zeichen in Hochkomma, ein String in
Anführungszeichen gesetzt?
Fabian Hoemcke schrieb:> Signal-Definitionen, also die Zuweisung, wird mit dem Operator "<="> gemacht, jedoch nicht, bei der Deklaration. Dann wird der Operator für> die Variablen-Deklaration ":=" verwendet. Wieso?
Das ist einfach so... ;-)
Viel störender ist doch, dass es verschiedene Syntaxelemente für
Prozesse und nebenläufige Zuweisungen gibt. Oder?
Christian R. schrieb:> Kann man den> eigentlich mittlerweile über TCL steuern?
Das kann ich Dir jetzt nicht sagen.
Hatte bisher nie nie Not damit arbeiten zu müssen.
Generell aber hätte ich eine andere Frage, da Du sagst, Du arbeitest
täglich 8h damit.
Kennst Du folgenden Effekt:
Ich habe (in Schematic) ein Programm erstellt, die Schaltung
funktioniert "fast" perfekt. Sowohl in der Simulation als auch auf dem
Board (Nexys2 1200k). Ich habe die Schaltung angepasst, lediglich 2
Inverter hinzugefügt. In der Simulation funktioniert die Schaltung
wunderbar. Auf dem Bord nicht. Dort werden die oberen 4 LEDs (LD4..LD7)
nicht angesteuert. Dann habe ich das selbe BIT-File bei einem
Kommilitonen auf dem Board ausprobiert und dort funktioniert es perfekt.
Auf dem Board eines dritten wiederum nicht. Dabei habe ich an den
Einstellungen der LEDs nichts geändert. Entferne ich die beiden Inverter
vor dem NOR wieder, klappt es wieder mit den LEDs, nur halt die Logik
funktioniert logischerweise nicht mehr.
Die Schaltung soll lediglich sekundenweise hochzählen, als Clock liegt
B8 an und das Ergebnis als BCD auf die 8 LEDs wieder ausgeben.
Bitte verstehe mich jetzt nicht falsch. Ich möchte nicht, dass Du mir
jetzt das Programm debugst. Das ist mein Job, das ist mir klar. ;) Mich
würde nur mal interessieren, ob solche Kuriositäten im VHDL-Alltag
normal sind und wo ich den Fehler suchen sollte.
Vielen Dank
Lothar Miller schrieb:> Fabian Hoemcke schrieb:>> Jetzt geht es, wenn in ALLEN Prozessen das WAIT; enthalten ist, Naja.> Naja, das ist VHDL...> Ein Prozess hat entweder (mindestens) 1 wait oder eine Sensitivliste.>> Fabian Hoemcke schrieb:>> Erst, so scheint es, machen die alles richtig und setzten auf Pascal>> und nicht wie sonst üblich eines der Millionen Basic-Derivate.> Diese Denkweise ist (wie Christian schon angemerkt hat) grundlegend> falsch. VHDL ist keine Programmiersprache. Es ist eine> Hardwarebeschreibungssprache. Und dann ist das wie wenn du sagst: ein> Schiff schwimmt einfach anders als ein LKW. Das muß so sein. Dafür ist> ein Schiff ausgelegt, ein LKW dagegen nicht.
Mir ging es hier um die Syntax. Eben das selbe, dass auch Du weiter
unten monierst.
>> Fabian Hoemcke schrieb:>> 1. Watt???> = Spannung mal Strom.>> 2. VHDL ist objektorientiert?> Ja, denn die ganzen Datentypen sind Objekte und du kannst deine eigenen> Rechenoperationen für diese Objekte definieren.>> 3. Man kann Operatoren überladen?> Sieh dir einfach mal den Quelltext für dein numeric_std an:> http://www.csee.umbc.edu/portal/help/VHDL/packages/numeric_std.vhd> Da siehst du, dass für jede Manipulation zweier Objekte eine Funktion> definiert ist (sein muß).>> 4. Wie?> Schreib deine eigene Berechnungsfunktion.>> 5. Wieso?> Damit du eigene neue Objekte anlegen und miteinender bzw. mit> existierenden Objekten verrechnen kannst.>> 6. Warum schreibt ISE für eine Anzahl 0 die Zahl in Hochkommata?> Warum wird in C ein einzelnes Zeichen in Hochkomma, ein String in> Anführungszeichen gesetzt?
Das kann ich Dir erklären. Aber ich denke, das weißt Du genauso gut wie
ich.
Hier aber, geht es nicht darum, beispielsweise einer Standart_Logic
einen Wert wie etwa '1' zuzuweisen, sondern darum, dass der Compiler
oder was auch immer in einer Fehlermeldung in einer Erwähnung einen
nummerischen Wert in Hochkommata setzt.
Ungefähr so als würde man auf dem Handy /" '10' verpasste Anrufe"/ lesen
oder "Es wurden '4' Dateien erzeugt!".
>>> Fabian Hoemcke schrieb:>> Signal-Definitionen, also die Zuweisung, wird mit dem Operator "<=">> gemacht, jedoch nicht, bei der Deklaration. Dann wird der Operator für>> die Variablen-Deklaration ":=" verwendet. Wieso?> Das ist einfach so... ;-)> Viel störender ist doch, dass es verschiedene Syntaxelemente für> Prozesse und nebenläufige Zuweisungen gibt. Oder?>
1
>-- Variante 1
2
>process(a,b,c)begin
3
>ifa='1'then
4
>y<=b;
5
>else
6
>y<=c;
7
>endif;
8
>endprocess;
9
>
10
>-- Variante 2
11
>y<=bwhena='1'elsec;
12
>
> Warum kann ich das nicht auch so schreiben:>
1
>-- Variante 3
2
>process(a,b,c)begin
3
>y<=bwhena='1'elsec;
4
>endprocess;
5
>
6
>-- Variante 4
7
>ifa='1'then
8
>y<=b;
9
>else
10
>y<=c;
11
>endif;
12
>
> Das ist doch wirklich störend...
Das ist eben das, dass ich auch beklagt hatte.
Nur würde ich als Beispiel gerne auch folgendes sehen:
1
-- Variante 4
2
whena='1'theny<=belsey<=c;
Gerne auch mit end when;
Das eine für sequenzielle Verzweigungen und das andere für parallele.
Das wäre konsistent und nachvollziehbar.
Gruß
Fabian
@Christian R.
Ha, jetzt "geht" es.
Ich habe jetzt einfach die Aufgabe weiter gemacht. Der 2. Counter muss
bei 6 zurückgesetzt werden, so dass man im Endeffekt eine
Sekundenanzeige hat. Also habe ich dessen Ausgänge passend ge-NAND-et
und erstmal Testweise auf den JK-Eingang zurückgeführt. Mir ist jetzt
klar, dass ich J und K einzeiln wieder rausführen muss um vernünftig zu
resetten.
Die Funktionalität des Programms ist aber im Grunde egal.
Mir ging es nur darum zu zeigen, dass ich keine, in meinen Augen,
entscheidenden Änderungen vorgenommen habe und schwups, funktioniert es
auf meinem Board.
Es bleiben die selben Fragen: Passiert sowas häufig und wo können die
Fehlerquellen liegen.
Gruß und Danke
Fabian
Fabian Hoemcke schrieb:> Zweites kann ich an der Aufgabenstellung leider nichts ändern. Wenn> Schematic gefordert ist, dann mache ich es in Schematic.
Darf man erfahren an welcher Einrichtung solche Aufgaben gestellt
werden?
(NSN = NokiaSiemensNetworks?)
Duke
@Duke Scarring
Nein! Bin nicht mehr bei NSN. ^^
Studiere jetzt an der Beuth-Hochschule für Technik in Berlin.
Sind auch noch die ersten Übungen. Es wird jetzt vermehrt VHDL.
Fabian Hoemcke schrieb:>> -- Variante 2>> y <= b when a='1' else c;>> > Warum kann ich das nicht auch so schreiben:>> -- Variante 4>> if a='1' then>> y <= b;>> else>> y <= c;>> end if;
Das hängt mit der englischen Sprache zusammen, "if" ist eben nicht
gleichbedeutend mit "when"!
Ein "when" beschreibt eine Bedingung die dauernd/laufend gilt.
Ein "if" beschreibt eine Entscheidung, die nur zu einem bestimmten
Zeitpunkt" getroffen wird, und zwar in der SEQUENTIELLEN Abarbeitung der
Statements im Prozess.
Die Designer von VHDL haben halt keine Rücksicht darauf genommen, dass
wir im Deutschen beidemale das Wort "wenn" verwenden.
-- ISIM: Type std_ulogic does not match with a string literal
30
-- ALDEC: Invalid aggregate.
31
-- c <= ( "11", x, y, z, others => '0' );
32
33
-- ISE alter Parser: No array or record type can be found that has elements of types matching the aggregate.
34
-- ISE neuer Parser: Synthese mit XST ok
35
-- ISIM: y,z sind um 1 vesetzt
36
-- ALDEC: Associations in array aggregate must be either all named or all positional.
37
-- c <= ( x, 3=>y, 2=>z, others => '0' );
38
39
-- ISE alter Parser: No array or record type can be found that has elements of types matching the aggregate.
40
-- ISE neuer Parser: Synthese mit XST ok
41
-- ISIM: y um 1 vesetzt, z nicht mehr im Vektor
42
-- ALDEC: Associations in array aggregate must be either all named or all positional.
43
-- Synplify: ignoriert Index ohne Meldung --> x&y&z&"00000" beachte :z+y
44
d<=(x,3=>y,0=>z,others=>'0');
45
46
-- Synplify: ignoriert Index ohne Meldung --> x&z&y&"00000" beachte :z+y
47
-- e <= ( x, 0=>z, 3>y, others => '0' );
48
49
-- ISE alter Parser: No array or record type can be found that has elements of types matching the aggregate.
50
-- ISE neuer Parser: Synthese mit XST ok
51
-- ISIM: y,z sind um 1 vesetzt
52
-- ALDEC: Associations in array aggregate must be either all named or all positional.
53
-- Synplify: ignoriert Index ohne Meldung --> x&y&z&"00000"
54
e<=(x,2=>y,4=>z,others=>'0');
55
56
57
endBEHAVIOR;
Insgesamt ein sehr undurchschaubares Bild.... :-/
Man sollte also unbedingt bei dem bleiben, was im Standard steht, und
sich hier nicht auf eine halbherzige Implementierung verlassen. Ich
werde in solche Fällen weiterhin den & Operator verwenden...