Hallo,
ich bin gerad dabei eine kleine Übungsaufgabe in VHDL zu machen.
Es handelt sich dabei um eine Steuerung für eine Ampelkreuzung.
Als Hardware soll der Spartan 3 verwendet werden, dem ein 50MHz
Taktsignal zugeführt wird.
Da bei meiner "Ampel" die kleinste vorkommende Zeit bei 0,5s liegt,
wollte ich aus den 50MHz den erforderlichen Takt von 2Hz ableiten.
mit diesem 2Hz-Takt würde ich dann einen Vorwärtszähler programmieren,
so dass ich definierte Eingangswerte habe, mit denen ich dann die
Zustandsübergänge realisieren kann.
Ist dieser Ansatz prinzipiell so richtig/gut?
Als momentan frage ich mich, wie ich konkret den 2Hz-Takt ableiten kann?
Ich müsste eine Prozess konstruieren, in dem nur bei jedem 25*10^6
Aufruf ein neues Takt-Signal "2HZCLK" gesetzt wird?
also brauche ich da irgendwie einen "sehr großen" Zähler?
kann man so einen Takt nicht auch anders ableiten?
Olli R. schrieb:> also brauche ich da irgendwie einen "sehr großen" Zähler?>> kann man so einen Takt nicht auch anders ableiten?
Ein 17bit Zähler ist ein Klacks. Ja so macht mans achte aber darauf dass
du das heruntergeteilte Signal als Clock Enable und nicht als Takt
verwendest
Du kannst auch ein 25bit LFSR nehmen, ihn auf 25*10^6 zyklen verkürzen
und
so deinen 2Hz Takt herleiten, oder auch gleich ein 27bit LFSR nehmen und
damit dein 0.5Hz Takt herleiten. Wie man da auf einen 17bit Zähler kommt
weiß ich nicht, einfacher zu kodieren ist aber ein Zähler welcher die
25*10^6 direkt zählt, normalerweise hast du in diesem Baustein genügend
resourcen dass du dir da keine Gedanken machen musst.
Chris schrieb:> Wie man da auf einen 17bit Zähler kommt> weiß ich nicht, einfacher zu kodieren ist aber ein Zähler welcher die> 25*10^6 direkt zählt, normalerweise hast du in diesem Baustein genügend> resourcen dass du dir da keine Gedanken machen musst.
Ich habe mich im Eifer des Gefechts auch um 2^8 vertan und meinte diese
Lösung ;)
D. I. schrieb:> Ja so macht mans achte aber darauf dass> du das heruntergeteilte Signal als Clock Enable und nicht als Takt> verwendest
Ok d.h. ich nehme meinen Ursprünglichen Clock von 50MHz und würde eine
Abfrage inetwa wie folgt machen:
if CLK = '1' and CLK'event then
if ENABLE = '1' then
...
...
d.h. ich mache mit meinem "ENABLE" also dem 2Hz Signal keine
Flankenabfrage?
warum kann ich den das nicht direkt verwendet bzw. wie sähe das den
richtig aus?
Olli R. schrieb:> d.h. ich mache mit meinem "ENABLE" also dem 2Hz Signal keine> Flankenabfrage?
genau so ist es.
Naja was kein Takt ist soll man nicht als Takt verwenden, gibt gneug
threads hier im Forum die das Problem dabei beleuchten.
Aber vielleicht kaut es dir Lothar zum 1466325784. Mal auch nochmal vor
;) so eine Buddhageduld habe ich leider nicht
D. I. schrieb:> Aber vielleicht kaut es dir Lothar zum 1466325784. Mal auch nochmal vor> ;) so eine Buddhageduld habe ich leider nicht
Ok nee kein Thema dann werde ich das mal nächste Woche in ner Vorlesung
fragen ;)
kann ich meine zählvariable, die ich z.B. wie folgt deklariere:
" signal COUNTER2HZ: bit_vector(24 downto 0); "
ähnlich wie in C "auch innerhalb eines Prozesses" mit z.B.
COUNTER2HZ <= COUNTERHZ +1;
-- inkrementieren?
if COUNTER2HZ='25000000' then -- kann ich '25000000' so schreiben?
ENABLE2HZ ='1';
COUNTER2HZ <= '0';
elsif
ENABLE2HZ = '0'
Olli R. schrieb:> Da bei meiner "Ampel" die kleinste vorkommende Zeit bei 0,5s liegt
Dann hast du offenbar noch keine Fußgängertaste... ;-)
Olli R. schrieb:> kann ich meine zählvariable, die ich z.B. wie folgt deklariere:> " signal COUNTER2HZ: bit_vector(24 downto 0); "
Vergiss das bit und den bit_vector am besten gleich wieder und verwende
die "üblichen" Vektoren: std_logic, unsigend, signed. Und zum Zählen am
einfachsten einen integer...
http://www.lothar-miller.de/s9y/archives/14-Numeric_Std.html> ähnlich wie in C
Vergiss C und die dahinterstehende Denkweise sofort. Versuch nicht
mal, nur wegen einer syntaktischen Nähe auch eine funktionale Nähe zu
suchen.
> "auch innerhalb eines Prozesses" mit z.B.
(Vorerst) eigentlich nur dort...
> COUNTER2HZ <= COUNTERHZ +1;
So wirst du noch öfter über die sehr strenge Typprüfung stolpern
Mit einem Integer geht das aber problemlos.
> if COUNTER2HZ='25000000' then -- kann ich '25000000' so schreiben?
Nein.
> ENABLE2HZ ='1';
Falsch.
> COUNTER2HZ <= '0';
hmm...
> elsif> ENABLE2HZ = '0'
Und jetzt?
Sieh dir mal mein Beispiel eines Lauflichts an (eine Ampel ohne
Fußgängertaste ist eigenlich nichts anderes):
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html
Und vor ichs vergesse. Leih dir ein Buch zum Thema VHDL aus:
VHDL-Synthese Reichardt&Schwarz
D. I. schrieb:> Aber vielleicht kaut es dir Lothar zum 1466325784. Mal auch nochmal vor
Du hast mitgezählt... :-o
Ich verweise auf die Suche mit den Begriffen "Anfänger Postulate" hier
im Forum:
http://www.mikrocontroller.net/search?query=anf%C3%A4nger+postulate&forums[]=9&max_age=-&sort_by_date=1
OK ich hab jetzt mal einen Frequenzteiler 50MHz auf 2Hz auf Grundlage
von Lothar Millers Frequenzteiler für das Lauflicht.
Jetzt müsst' ich doch mit diesem CLKENABLE einen Binärvorwärtszähler
realisieren können, dessen Zählwerte für den Übergang von Zustand zu
Zustand dienen können?
Olli R. schrieb:> auf Grundlage von Lothar Millers Frequenzteiler für das Lauflicht.
Nein. Hast du nicht.
Denn sowas findest du bei mir nicht:
1
ifCLK='1'andCLK'eventthen
Was, wenn CLK vorher 'H' war oder 'X' oder 'U'?
Richtig: deine Simulation sieht einen Takt, wo keiner ist...
Deshalb: rising_edge() oder falling_edge().
Olli R. schrieb:> Jetzt müsst' ich doch mit diesem CLKENABLE einen Binärvorwärtszähler> realisieren können, dessen Zählwerte für den Übergang von Zustand zu> Zustand dienen können?
Ja, das ist soweit die richtige Vorgehensweise...
>ich bin gerad dabei eine kleine Übungsaufgabe in VHDL zu machen.>Es handelt sich dabei um eine Steuerung für eine Ampelkreuzung.>>Als Hardware soll der Spartan 3 verwendet werden, dem ein 50MHz>Taktsignal zugeführt wird.>>Da bei meiner "Ampel" die kleinste vorkommende Zeit bei 0,5s liegt,>wollte ich aus den 50MHz den erforderlichen Takt von 2Hz ableiten.
DY, erster Versuch @ Fitz? HAW-Hamburg?
OK irgendwie ist mir das alles doch noch ziemlich befremdlich.
Ich das ganze nochmal überdacht und den Versuch eines "Zustanddiagrammes
gemacht (siehe Anhang). Die Aufgabe ist hier zu finden:
http://users.etech.haw-hamburg.de/users/fitz/DY_FTZ_Labor_1.pdf
( Ich möchte hier natürlich kein komplette Lösung vorgekaut bekommen,
sonst wäre der Lernerfolg -> 0 aber ein paar Ansätze wären nicht
schlecht)
Also wie man den Folgezustand berechnet, kann ich mir denken bzw. das
ist mir soweit klar.
Bei einem Takt alle 0,5 s muss ich ja die meisten Zustände mehrfach
hintereinander haben.
Dies könnte man ja wie in dem hier angefügten Diagramm mit Zählern
realisieren.
Aber wie kann ich die Abhängigkeit von 4 externen Signal da einbringen.
z.B. möchte ich die Zähler für die beiden Grünphasen von 4 Sensoren in
der Fahrbahn abhängig machen?
Dann gibt es die Grünanforderung von Fußgänger, d.h. während eines
regulären Durchlaufs soll ein "Signal" gesetzt werden, das dann
dazuführt, dass am Ende des Durchlaufs einmal eine "Fußgängergrünphase"
durchlaufen wird.
wie kann man so ein Signal, dass von 2 Eingänge abhängig ist setzen und
speichern und dann am Ende der Fußgängergrünphase wieder zurücksetzen?
Der RESET soll, wenn er gesetzt ist dazuführen, dass (egal in welchem
Zustand ich mich befinde) in den Gelb-Blink-Modus gewechselt wird!
wenn RESET wieder 0 ist soll diese Blinkphase nach 1,5s Dauergelb wieder
verlassen werden.
Wie könnte ich die genannte Abhängigkeit von Eingangssignal in das
Zustandsdiagramm aufnehmen?
Olli R. schrieb:> Ich das ganze nochmal überdacht und den Versuch eines "Zustanddiagrammes> gemacht (siehe Anhang).
Das was da links unten steht "asynchron hierher, wenn Reset ='1'" und
"solange Reset = '1' wird zwischen diesen 2 Zuständen gewechselt" lässt
sich für mich nicht in Deckung bringen... :-o
Und zudem wird in der Aufgabenstellung nichts von einem asynchronen
Reset erwähnt. Dann lass den ganz einfach weg.
> wie kann man so ein Signal, dass von 2 Eingänge abhängig ist setzen und> speichern
Du nimmst ein Flipflop, das mit 50 MHz getaktet wird (Einsynchronisieren
des asynchronen externen Signals nicht vergessen)
> und dann am Ende der Fußgängergrünphase wieder zurücksetzen?
Du setzt das FF einfach wieder zurück.
Immer im Hinterkopf behalten:
In der Hardware wird das alles komplett parallel abgebildet. Du hast
also gleichzeitig die Abfrage der Fußgängertaster und die Abarbeitung
deiner FSM.
Lothar Miller schrieb:> Das was da links unten steht "asynchron hierher, wenn Reset ='1'" und> "solange Reset = '1' wird zwischen diesen 2 Zuständen gewechselt" lässt> sich für mich nicht in Deckung bringen... :-o>> Und zudem wird in der Aufgabenstellung nichts von einem asynchronen> Reset erwähnt. Dann lass den ganz einfach weg.
Ich beziehe mich auf die Blinkanforderung für die Nacht:
Heißt das, dass ich dafür einen Eingang (Taster) nehme, der mir ein
Flipflop setzt (wenn Eingang = 1) und das FF zurücksetzt, wenn Eingang =
0?
FF-Signal wird dann für die Verzweigung im Automatengraph verwendet!
zu den Fahrbahnsensoren bzw. Fußgängergrünanforderung:
Heißt das, dass ich die Eingangssignale (die 4 Fahrbahnsensoren) als
nebenläufige Anweisung bzw. als Prozeß der mit 50MHz getakt wird (z.B.
indem ich ein FF realisere) "verarbeite" und somit ein weiteres Signal
"Hauptstraße länger Grün" generiere?
Lothar Miller schrieb:>> und dann am Ende der Fußgängergrünphase wieder zurücksetzen?> Du setzt das FF einfach wieder zurück.
Kann ich für dieses Zurücksetzen soetwas z.B. schreiben:
if zustand = 12 and zaehler = 14 then
-- "Zustand12 = Fußgängerampeln Grün; letzte Durchlauf des Zustandes 12
--> Zähler = 12"
fuss_anforderung = 0; end if;
--> Ich hab ja bei meinen ersten Versuchen gemerkt, dass ich versucht
habe, in mehr als einem Prozeß ein Signal gleichzeitig zu definieren!
Dass das nicht geht ist mir jetzt so langsam klar, da ja alles quasi
gleichzeitig läuft.
Aber eine Abfrage von Signalen ist doch auch parallel möglich (also
mehrere Prozesse können dasselbe Signal als "Bedingung" nutzen? (ist ja
quasi nur "ein Stück Draht, dass auf mehrere Eingänge zugleich gelegt
wird"?!
Olli R. schrieb:> Kann ich für dieses Zurücksetzen soetwas z.B. schreiben:
Grundsätzlich ja.
Ich würde diese Fußgängeranforderung also grog etwa so machen:
1
signalsr_ft:std_logic_vector(2downto0):="000";-- Schieberegister zum Eintakten und Flankenerkennung Fussgaengertaste
2
processbegin
3
waituntilrising_edge(the_one_and_only_clock);
4
sr_ft<=sr_ft(1downto0)&eingang_fussgaengertaste;
5
if(sr_ft(2downto1)="01")then-- steigende Flanke an der Fussgaengertaste
6
fuss_anforderung<='1';
7
endif;
8
if(zustand=12andzaehler=14)then-- dein Beispiel
9
fuss_anforderung<='0';
10
endif;
11
endprocess;
Olli R. schrieb:> Aber eine Abfrage von Signalen ist doch auch parallel möglich (also> mehrere Prozesse können dasselbe Signal als "Bedingung" nutzen?
Ja richtig.
> FF-Signal wird dann für die Verzweigung im Automatengraph verwendet!
Du verknüpfst hier 2 komplett unterschiedliche Abstaktionsebenen. Im
Automatengraph interessiert nur die theoretische Schrittfolge. Wie das
irgendwie auf Hardware abgebildet wird, ist zu der Zeit noch
uninteressant.
Dein Automat wird später sowieso in irgendwelche FFs abgebildet...
> Heißt das, dass ich die Eingangssignale (die 4 Fahrbahnsensoren) als> nebenläufige Anweisung bzw. als Prozeß der mit 50MHz getakt wird (z.B.> indem ich ein FF realisere) "verarbeite" und somit ein weiteres Signal> "Hauptstraße länger Grün" generiere?
Die Fussgängertaste und die Fahrbahnsensoren sind nur Hilffsignale,
deren Erzeugung im "großen" Automatendiagramm gar nicht auftauchen. Wenn
du willst, kannst du den VHDL-Code von oben auch in ein Zustandsdiagramm
malen...
> als Prozeß der mit 50MHz getakt wird
JEDER getaktete Prozess wird mit diesem Takt angesteuert. Es gibt nur 1
Takt im ganzen Design...
sorry aber irgendwie muss ich zu diesem Teil nochmal was fragen:
also du deklarierst einen std_logic_vector mit der Länge 3Bit!
dann verkettest du die unteren beiden Bit dieses Vektors "sr_ft" mit
eingang_fussgaengertaster!
> sr_ft <= sr_ft(1 downto 0) & eingang_fussgaengertaste; --> speichert er jetzt
eingang_fussgangertaster in sr_ft(2)?
dann fragst du ab, ob die oberen Bits von "sr_ft" "01" sind?
wie was hätte denn nicht auch eine einfache Bit-Variable oder std_logic
Variable gereicht?
> if (sr_ft(2 downto 1) = "01") then -- steigende Flanke an der
also nur if eingang_fussgaengertaste = "1" then ??
> fuss_anforderung <= '1';
Moment jetzt glaube ich es zu verstehen:
sr_ft <= sr_ft(1 downto 0) & eingang_fussgaengertaste;
hiermit wird also "eingang_fussgaengertaste an die Stelle 0 von sr_ft
gepackt. korrekt?
dadurch fällt der höchste Wert in sr_ft weg!
if (sr_ft(2 downto 1) = "01") then -- steigende Flanke an der
Fussgaengertaste
Der Wert der Fussgaengertaste wird also wie folgt durch geschoben:
sr_ft: Bit 2 1 0
0 0 1 <-- Fussgängertaste gedrückt
0 1 1 <-- Taste immer noch gedrückt und Ausgang wird
gesetzt 1 1 1 <-- Ausgang ist gesetzt und Taste gedrückt
1 1 0 <-- Taste wird losgelassen
1 0 0 <-- Taste losgelassen; ausgang bleibt die ganze
Zeit gesetzt 0 0 0 <-- Taste losgelassen ("komplett durchgelaufen")
Somit wird das FlipFlop nur einmal gesetzt während
sr_ft = 0 1 1 oder 0 1 0 (der zweite Zustand ist aber
unwahrscheinlich, dann müsste die Person, die drück schon nach 20 bis 40
ns wieder losgelassen haben! ;)
Ich hoffe meine "Verständniserläuterung" war verständlich.
Olli R. schrieb:> Somit wird das FlipFlop nur einmal gesetzt während> sr_ft = 0 1 1 oder 0 1 0
Richtig. Nur an der steigenden Flanke wird das FF gesetzt.
> (der zweite Zustand ist aber unwahrscheinlich, dann müsste die Person,> die drück schon nach 20 bis 40 ns wieder losgelassen haben! ;)
Oder die Taste müsste einen (anfangs) schlechten Kontakt haben, oder
prellen, oder wasweißich...
> Ich hoffe meine "Verständniserläuterung" war verständlich.
Ich habe verstanden, dass du ein Schieberegister und die
Flankenauswertung verstanden hast.
> oder 0 1 0
Wenn du jetzt noch ein klitzekleinwenig weiter gedacht hättest... :-/
... dann wäre dir aufgefallen, dass diese mitllere '1' auch nur ein
kleiner Störspike sein könnte... :-o
Aus diesem Grund ist es in der harten Praxis ratsam, eine Taste/Sensor
nicht direkt mit dem Systemtakt einzulesen, sondern mit z.B. 10ms
Abstand zwischen den "Schiebeoperationen" abzuwarten.
Und zudem das Schieberegister etwas breiter zu machen und mehr Bits
abzufragen. Also z.B. auf "01111" zu vergleichen. Bei diesem
Schieberegister müsste das Signal also mindestens 40ms stabil angelegen
haben (4 x '1')...
Siehe dort: http://www.lothar-miller.de/s9y/categories/5-Entprellung
Lothar Miller schrieb:> Aus diesem Grund ist es in der harten Praxis ratsam, eine Taste/Sensor> nicht direkt mit dem Systemtakt einzulesen, sondern mit z.B. 10ms> Abstand zwischen den "Schiebeoperationen" abzuwarten.
Ok klar also habe ich so schon mal ne leichte Entprellung!
ok für das halten von 10ms müsste ich in diesem Fall eine Zähler haben,
der den Wert 500 hat (bei Takt alle 20ns).
Ok ich werd die Tage mich dann auf das eigentliche Programm
konzentrieren und dann das Entprellen mit einbauen!
Olli R. schrieb:> ok für das halten von 10ms müsste ich in diesem Fall eine Zähler haben,> der den Wert 500 hat (bei Takt alle 20ns).
Noch ein paar Nullen (3 Stück) dazu, aber die Idee passt... ;-)
Und dieses "heruntergeteilte" Signal verwendest du dann aber nicht als
Takt, sondern als Clock-Enable!
> Ok klar also habe ich so schon mal ne leichte Entprellung!
Damit?
>> Also z.B. auf "01111" zu vergleichen.
Richtig. Aber eben nur eine sehr sehr kurze...
OK jetzt habe ich es mal versucht umzusetzen.
Ich kann es leider nicht kompilieren.
Ich bekomme vom ModelSim kompiler diverse Fehlermeldungen, die ich so
nicht genau interpretieren kann.
Des weiteren ist mir noch nicht genau klar, wie ich es schaffe, das
quasi
asynchron in den Blink-Nacht-Modus gewechselt wird?
Quasi wie ich über "NACHT_ANF" das erste Mal in den Zustand NACHT1
kommen kann?
Achso ich gehe nun von einem Systemtakt von f = 1KHz aus!
Olli R. schrieb:> Ich bekomme vom ModelSim kompiler diverse Fehlermeldungen, die ich so> nicht genau interpretieren kann.
Welche denn?
> --- nicht synthetisierbare Testbench Prozesse:---
So ist das zumindest sehr unüblich.
IdR. ist eine Testbench ein VHDL-Modul ohne Ports. In dieses Modul wird
die zu testende Komponente eingebunden...
> ANFORDERUNG_FUSS: process(GN_FU_ANF_H, GN_FU_ANF_N)> begin> if CLK = '1' and CLK'event then ...>> FAHRBAHNSENS: process(SENS1, SENS2, SENS3, SENS4)> variable SENSKOMB: bit_vector (3 downto 0);> begin> if CLK = '1' and CLK'event then ...
Diese Prozesse sind AUSSCHIESSLICH auf den CLK sensitiv, denn NUR eine
Änderung von CLK kann ein neues Ergebnis bewirken. Also ist die
Sensitivliste falsch!
> variable SENSKOMB: bit_vector (3 downto 0);> SENSKOMB <= SENS1 & SENS2 & SENS3 & SENS4;> case SENSKOMB is
Das ginge ohne Variable auch so:
> case SENS1 & SENS2 & SENS3 & SENS4 is
Und der Klassiker bei der Zwei-Prozess-Schreibweise:
Eine kombinatorische Schleife... ;-)
1
-- Übergangsschaltnetz (Folgezustandsberechnung)
2
UE_SN:process(ZAEHLER,ZUSTAND,FU_ANF_SET,H_ZAHL,N_ZAHL)-- hier fehlt noch AUSGANG, denn eine ÄNDERUNG von AUSGANG ändert auch AMPEL_H, AMPEL_N...
3
begin
4
AUSGANG<=ALLEAN;
5
AMPEL_H<=AUSGANG(9downto7);
6
AMPEL_N<=AUSGANG(6downto4);
7
:
8
FOLGE_Z<=INIT;
9
caseZUSTANDis
10
whenINIT=>AUSGANG<=ALLEAN;
11
-- Achtung, jetzt kommt ein Zähler im kombinatorischen Teil einer 2-Prozess-FSM
12
if(ZAEHLER<=7)
13
thenFOLGE_Z<=INIT;-- solange der Zähler kleiner gleich 7 ist wird im Zustand INIT verweilt
14
zaehler<=ZAEHLER+1;-- der Zähler wird inkrementiert
15
-- ^--- Zähler können nur im getakteten Teil realisiert werden !!!!
Zähler können nur im getakteten Teil realisiert werden, denn die müssen
ja speichern können. Und speichernde Elemente sind getaktete Elemente
und damit Flipflops (kommm mir jetzt bloß keiner mit Latches, damit kann
man keine Zähler bauen).
http://www.lothar-miller.de/s9y/categories/36-Kombinatorische-Schleife
Lothar Miller schrieb:> when INIT => AUSGANG <= ALLEAN;> -- Achtung, jetzt kommt ein Zähler im kombinatorischen Teil
einer 2-Prozess-FSM
könnte ich diesen Zähler dann in dem getakteten Prozess, in dem ich auch
sage:
ZUSTAND <= FOLGE_Z
inkrementieren:
ZAEHLER = ZAEHLER +1?
und dann durch eine abfrage z.b zaehler_reset = 1
dann ZAEHLER = 0;
wobei ich "zaehler_reset" bei der zustands_zuweisung gegebenenfalls
setze?
AUSGANG <= ALLEAN;
AMPEL_H <= AUSGANG(9 downto 7);
AMPEL_N <= AUSGANG(6 downto 4);
dieser Teil ist so auch nicht möglich:
Ich möchte doch nur die jeweiligen Bits einem AMPEL_SIGNAL zuweisen?
aber abgesehen von dem Zähler kann ich das so machen? (ich habe leider
gerade keine Möglichkeit zu testen)
Olli R. schrieb:> dieser Teil ist so auch nicht möglich:
Die Punkte : sind Abkürzungspunkte, Fortsetzungspunkte wie die hier ...
Ich muß ja nicht deinen ganzen Quelltext kopieren, wenn ich nur Teile
davon anspreche...
> könnte ich diesen Zähler dann in dem getakteten Prozess...
Ja, und nur dort.
Und sieh dir wie gesagt die Sensitivlisten nochmal an, sonst ist deine
Simulation (und nur die interessiert sich dafür) schlicht falsch!
Olli R. schrieb:> AMPEL_H <= AUSGANG(9 downto 7);> AMPEL_N <= AUSGANG(6 downto 4);
Die Punkte : sind Abkürzungspunkte, Fortsetzungspunkte wie die hier ...
ich meinte,dass AMPEL_N <= AUSGANG(6 downto 4);
nicht wie von mir gewünscht BIt 6 bis Bit 4 an AMPEL_N "gibt".
> könnte ich diesen Zähler dann in dem getakteten Prozess...
Ja, und nur dort.
ok das Inkrementieren kann ich also im getakteten Prozess machen.
Könnte ich aber das Rücksetzen des ZAEHLERS (ZAEHLER <= 0); trotzdem
noch
im Prozeß für die Zustandsberechnung machen? oder hätte ich dann wieder
die Kombinatorische Schleife?
Olli R. schrieb:> Könnte ich aber das Rücksetzen des ZAEHLERS (ZAEHLER <= 0); trotzdem> noch im Prozeß für die Zustandsberechnung machen?
Nein, denn auf das Signal ZAHLER darf nur 1 Prozess treiben.
> oder hätte ich dann wieder die Kombinatorische Schleife?
Wenn das ginge, dann hättest du einen asynchronen kombinatorischen
Reset. Und den kannst du brauchen wie ein Stück Hundesche..e am Schuh.
Glaubs mir.
Aber zum Glück gehts gar nicht... ;-)
Olli R. schrieb:> ich meinte,dass AMPEL_N <= AUSGANG(6 downto 4);> nicht wie von mir gewünscht BIt 6 bis Bit 4 an AMPEL_N "gibt".
Warum nicht?
Was tut er denn?
Wie schon erwähnt ist deine Sensitivliste unvollständig:
1
UE_SN:process(ZAEHLER,ZUSTAND,FU_ANF_SET,H_ZAHL,N_ZAHL)-- hier fehlt noch AUSGANG, denn eine ÄNDERUNG von AUSGANG müsste auch AMPEL_H, AMPEL_N... ändern
Lothar Miller schrieb:>> ich meinte,dass AMPEL_N <= AUSGANG(6 downto 4);>> nicht wie von mir gewünscht BIt 6 bis Bit 4 an AMPEL_N "gibt".> Warum nicht?> Was tut er denn?
Error: ampels.vhd(65): Prefix of slice name must be an array.
Ich kann diese Kompiler-Meldung nicht einordnen. (Auch Google half mir
noch nicht!)?
Das geht erst mal natürlich nicht:
Denn was wäre dann eigentlich AUSGANG(6 downto 4)?
Nein, mit deinen ENCODING geht das nicht!
Das ist lediglich ein kleiner Hinweis an das Synthesetool, doch bitte
die Codierung der oben angeführten Zustände so auszuführen:
Deshalb kann ohne Konvertierung vom einen Signal nichts auf das Andere
zugewiesen werden!
Machs wie der Rest der Welt:
Lass den Synthesizer seine FSM selber optimieren und weise die
Lampensignale abhängig von den Zuständen direkt zu (z.B. mit einem CASE
oder WHEN)...
Lothar Miller schrieb:> attribute ENUM_ENCODING of AUSGABE: type is "1111111111 1001001010 0000000000
0100100000 0011001010 1000011010 0101001010 1000101010 1101001010 1001101010
1001000101";
> Die Simulation kann damit nichts anfangen...>> Machs wie der Rest der Welt:> Lass den Synthesizer seine FSM selber optimieren und weise die> Lampensignale abhängig von den Zuständen direkt zu (z.B. mit einem CASE> oder WHEN)...
OK ja das ist mir jetzt auch gerad klar geworden also
dieses ENUM_ENCODING ist nur eine Anweisung an den Präprozessor!
Jetzt habe ich das Programm zumindest schon soweit gelöst, dass es
kompiliert wird.
Leider ist es so, dass das Programm nach dem es den Zustand "INIT" nach
7s das erste Mal verlassen hat, in den Zustand "REG1" wechselt dann geht
es aber aus irgendeinem Grund wieder in den Zustand INIT und dann wieder
in den Zustand REG1.
Er pendelt quasi nur zwischen den Zuständen INIT und REG1??
Olli R. schrieb:> dieses ENUM_ENCODING ist nur eine Anweisung an den Präprozessor!
Einen Präprozessor gibt es nicht.
Es ist ein Wunsch an den Synthesizer. Wenn der das versteht, setzt er
die Zustände so um. Wenn nicht, dann nicht. Aber normalerweise gibts
dann eine passende Warning/Info...
> Er pendelt quasi nur zwischen den Zuständen INIT und REG1??
Warum?
Um das herauszufinden ist eine Testbench da. Da kannst du ja sehen, was
kurz vor dem fehlerhaften Zustand passiert ist...
Mach mal deine "Testbench" aus der Beschreibung raus. Das ist so extrem
verwirrend...
BTW:
if ZAEHLER_RESET = '0'
then ZAEHLER <= ZAEHLER +1; end if;
if ZAEHLER_RESET = '1'
then ZAEHLER <= 0;
end if;
Das kannst du ohne jegliche Verhaltensänderung so schreiben:
if ZAEHLER_RESET = '0' then
ZAEHLER <= ZAEHLER +1;
else
ZAEHLER <= 0;
end if;
Oder gar so:
ZAEHLER <= ZAEHLER +1;
if ZAEHLER_RESET = '1' then
ZAEHLER <= 0;
end if;
Lothar Miller schrieb:> Mach mal deine "Testbench" aus der Beschreibung raus. Das ist so extrem> verwirrend...
Ok ich hab es jetzt so umgeformt, das es für die Synthese taugt,
allerdings
weiss ich jetzt nicht genau, wie man da die Testbenches macht.
Das war dann irgendwie mit force bei Modelsim?
Wie geht man da am besten vor?
P.S. sorry, dass ich so häufig hier nachfrage aber die Ampel ist ja
quasi mein erstes VHDl-Programm. ;)
Olli R. schrieb:> weiss ich jetzt nicht genau, wie man da die Testbenches macht.
2 Sachen sind nötig:
1. Eine Testbench hat keine Ports.
2. In diese Testbench (die den vollen Sprachumfang von VHDL nutzen kann)
wird dein Modell als Komponente eingebunden.
Sieh dir mal die PS2-Schnittstelle da an:
http://www.lothar-miller.de/s9y/archives/75-PS2-Tastatur.html
Da gibt es die eigentliche Entity PS2_Keyboard,
die in der Entity PS2_tb als Komponente eingebunden und stimuliert
wird...
> Das war dann irgendwie mit force bei Modelsim?
Das ist Murks. Ich habe das noch nie verwendet... :-/
BTW:
> Ok ich hab es jetzt so umgeformt, das es für die Synthese taugt,
Du hast dir aber beim Prozess
FAHRBAHNSENS: process(SENS1, SENS2, SENS3, SENS4)
Latches eingefangen. Das mag man nicht auf einem FPGA. Und die Synthese
weist dich darauf hin, ob du die Dinger tatsächlich willst und du dir
der Konsequenzen bewusst bist...
Latches gibt es, wenn in einer kombinatorischen Zuweisung nicht alle
Pfade auscodiert sind, und auch keine Defaultzuweisung da ist. Lies mal
VHDL-Synthese von Reichardt&Schwarz...
Die Konsequenzen von Latches sind (insbesondere, wenn sie wie bei dir)
kombinatorisch angesteuert werden, dass die Laufzeit nicht mehr
berechenbar und daher nicht mehr kontrollierbar ist.
EDIT:
> die Ampel ist ja quasi mein erstes VHDl-Programm. ;)
Ja, du machst zwei Schritte auf einmal und fällst aufs Maul (in Prosa
gesprochen). Besser hättest du zum Lernen erst mal ein Lauflicht (in
allen Variationen) beschrieben und verstanden...
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html
Lothar Miller schrieb:> Du hast dir aber beim Prozess> FAHRBAHNSENS: process(SENS1, SENS2, SENS3, SENS4)> Latches eingefangen. Das mag man nicht auf einem FPGA. Und die Synthese> weist dich darauf hin, ob du die Dinger tatsächlich willst und du dir> der Konsequenzen bewusst bist...> Latches gibt es, wenn in einer kombinatorischen Zuweisung nicht alle> Pfade auscodiert sind, und auch keine Defaultzuweisung da ist. Lies mal> VHDL-Synthese von Reichardt&Schwarz...
Ich glaube so sollte das "Latch" weg sein mit dem else habe ich doch
alle mögliche Fälle abgedeckt?
FAHRBAHNSENS: process(SENS1, SENS2, SENS3, SENS4)
begin
if ((SENS1 = '1' or SENS2 = '1') and SENS3 = '0' and SENS4 =
'0')
then H_ZAHL <= 11;
N_ZAHL <= 3;
else
H_ZAHL <= 9;
N_ZAHL <= 7;
end if;
end process FAHRBAHNSENS;
VHDL-Synthese hab ich hier schon rum liegen und die ersten 150Seiten die
letzten Tage gelesen und weitestgehend nachvollzogen.
Und dort wird das mit der Testbench allerdings so beschrieben, wie ich
es zuvor schon inetwa gemacht hab:
STIMULI oder TAKTGEN erstellen, keine Ports verwende also die Eingänge
vorrübergehend als Signale deklarieren.
Deine testbench bezogen auf Ps2 kann ich jetzt so nicht ganz
nachvollziehen!
Olli R. schrieb:> VHDL-Synthese hab ich hier schon rum liegen und die ersten 150Seiten die> letzten Tage gelesen und weitestgehend nachvollzogen.> Und dort wird das mit der Testbench allerdings so beschrieben
Das ist auch kein buch, in dem die Feinheiten von Testbenches erklärt
werden!
Es heißt nicht umsonst "VHDL-Synthese"...
> Ich glaube so sollte das "Latch" weg sein mit dem else habe ich doch> alle mögliche Fälle abgedeckt?
Ja.
> STIMULI oder TAKTGEN erstellen, keine Ports verwende also die Eingänge> vorrübergehend als Signale deklarieren.
Nein. Eine Testbench ändert überhaupt nichts am Testobjekt. Die
Testbench wird aussenrum gebaut und beinhaltet dein synthesefähiges
Modul. Die Testbench bildet/beschreibt die Umwelt deines Moduls (=Lampen
+ Taster + Sensoren).
Hier mal ein einfaches Beispiel einer PWM und einer entsprechenden
Testbench (=Takt und Comparewerte):
Und heraus kommt dann z.B. so eine Waveform wie im Anhang.
Allerdings ist eine Waveform keine sinnvolle Sache, wenn irgendwas
automatisiert geschen muß, weil z.B. die Compare-Daten aus einer Datei
gelesen werden und anschliessend überwacht werden soll, ob die richtige
Pulsweite herauskommt. Dafür gibt es dann Assertions und Text-IO und den
ganzen Sprachumfang von VHDL...
Jo
Cool Vielen Dank Lothar.
Mit deinem kleinen PWM-Beispiel konnte ich ne Menge anfangen.
Ich hab für mein Proggi auch so eine testbench erstellt und ich muss
sagen:
dadurch ist das alles ja weit übersichtlicher, da das eigentliche
Programm so verbleibt, wie es dann auch synthetisiert wird.
Dennoch hat es noch eine Weile gedauert aber nur, weil mir einige Fälle
in den Sinn gekommen sind, die bei so einer Ampel eher ungünstig sind.
Z.B.
wenn Fußgänger gerade Grün hatten, ist soll doch wenn in der
anschließenden Rot-Phase wieder eine Fußgänger-Grün-Anforderung kommt,
wenigstens eine der beiden Straßen eine Grünphase gehabt haben.
Mit einer zusätzlichen, zwischen zu speichernden "Variablen" bzw.
bit-signal ging das dann doch ganz gut.
Aber jetzt habe ich zumindest mal gesehen, welche Schwierigkeiten so bei
der VHDL-Programmierung bestehen und werden dann auch mal tiefer in ein
paar deiner Beispiele einsteigen.