Hallo,
ich bin gerade dabei mit VHDL ein bisschen rumzuspielen. Dazu habe ich
mir ein Buch gekauft und auch schon einige einfache Beispiele simuliert.
Jetzt habe ich den Lötkolben ausgepackt und eine CPLD von Xilinxs auf
eine kleine Platine gelötet mit 3 Tastern und 3 LEDs. Funktioniert so
weit so gut.
Ich habe ein paar kleine Tests gemacht und kam dann auf die Idee, dass
bei Tasterdruck eine LED angehen soll und bei erneuten Druck wieder aus.
Tastenentprellung ist mir erstmal egal, den Effekt müsste man ja
trotzdem sehen.
Wie bekommt man so was hin? Ich bekomme nur immer Fehlermeldungen, das
ich irgendwelche Latches generiert habe (bzw Warnungen)... oder geht das
nicht so einfach?
Mein erster Gedanke war dieser hier... (alle anderen haben ihren Zweck
auch nicht erfüllt :-D)
Wenn TASTER(0) sich ändert, also von 0 auf 1 springt oder umgekehrt wird
der Prozess ausgelöst .... hab nur die "interesanten" Codezeilen
rauskopiert:
type STATE_TYPE is (LED_ON, LED_OFF);
signal STATE : STATE_TYPE := LED_OFF;
......
process (TASTER(0),STATE)
begin
if (STATE = LED_OFF) then
STATE <= LED_ON;
else
STATE <= LED_OFF;
end if;
end process;
with STATE select
LED(4) <= '0' when LED_ON,
'1' when others;
achja benutze Xilinx Webpack 11
Bitte um HILFE :-)
Danke
Grüße
balou
also das sollte funktionieren
process (TASTER(0))
begin
if rising_edge(TASTER(0)) then
if (STATE = LED_OFF) then
STATE <= LED_ON;
else
STATE <= LED_OFF;
end if;
end if;
end process;
LED(4) <= '0' when LED_ON else '1';
Cool Danke funktioniert wirklich!
Ich hatt es ungefähr so probiert...
process (TASTER(0))
begin
if (TASTER(0)'event) then ....
dann gabs aber einen Error
line 64: unsupported Clock statement.
Ich dachte das wäre so ziemlich das gleiche???
Grüße
balou
Hm so funktioniert es ...
process (TASTER(0))
begin
if (TASTER(0)'event and TASTER(0) = '1') then
if (STATE = LED_OFF) then ......
warum darf man nicht TASTER(0)'event alleine verwenden????
Danke euch!! super Forum
Grüße
balou
balou schrieb:> warum darf man nicht TASTER(0)'event alleine verwenden????
Weil dies bedeuten würde, dass die Ausgangssignale auf beide Flanken
reagieren, also wenn Taster(0) sich von 0 auf 1 ODER von 1 auf 0 ändert.
Die normalen Flip Flips in einem CPLD oder FPGA reagieren aber nur auf
eine Flanke, also entweder aufsteigen oder abfallen, deshalb muss man
noch
TASTER(0)'event and TASTER(0) = '1'
schreiben. Das bedeutet, dass das Signale Taster(0) nun auf '1' ist und
sich gerade geändert hat (also kam es von 0 auf 1).
Du solltest Dir aber angewöhnen, "rising_edge(Taster(0)) zu schreiben,
das ist das selbe und besser lesbar.
Hallo...
Danke für euer Antworten, hat mir sehr weiter geholfen.
@ der mechatroniker
"Und einen Taster als Clock verwenden, ist -- gleich ob in einem CPLD,
FPGA oder ASIC -- mehr als mutig."
Wie würdest du das dann implementieren? Wenn ich eine Flanke eines
Tasters abfrage, warum ist das dann gleich ein Clock?
grüße
balou
>warum ist das dann gleich ein Clock?
Immer wenn du "event" oder "rising_edge" verwendest, wird das
entsprechende Signal an den Takteingang der Flipflops gelegt. Ein Takt
ist nicht einfach nur ein Signal, sondern ein Riesiges Netzwerk von sehr
schnellen Verbindungen zu allen FF. Da dein "Tastentakt" keinen
Definierten Zeitlichen Bezug hat, kann es zu Metastabilitäten kommen. In
einem Design sollte man nur einen Takt verwenden.
>Wie würdest du das dann implementieren?
Einen Counter den Systemtakt Zählen lassen, wenn die Taste Gedrückt ist.
Wird sie Losgelassen den Counter resetten. Hat der Counter den Wert x
erreicht, dann die Led umschalten. Das Loslassen der Taste musst du
natürlich ähnlich lösen.
Hallo,
habe leider nicht so ganz verstanden was du gesagt hast. Was genau hat
hier ein Schieberegister zu tun?
Ich habe den Code nun mal abgeändert, in der Hoffnung das getan zu haben
was du meintest :-D Hoffe ihr könnt ihr noch ein paar Tips geben?
Relevanter Codeteil... Rest im Anhang.
Deine Beschreibung wird bei einer angemessenen Taktfrequenz einfach das
Prellen des Tasters an die LED weitergeben. Tasterabfragen gehen anders:
http://www.lothar-miller.de/s9y/categories/5-Entprellung
Und, voila: da ist es, das Scheiberegister ;-)
So wie hier wäre das Verhalten deiner Beschreibung übrigens ganz ohne
Prozess und ohne signifikante Funktionseinschränkung kürzer beschrieben:
1
LED(4)<=notTASTER(0)whenrising_edge(CLK);
BTW:
Dein Prozess oben ist nur auf CLK sensitiv. TASTER(0) ist unnötig.
Als Tipp:
du brauchst in deinem ersten viertel VHDL-Jahr garantiert (!!!!) keine
Variable. Sicher nicht.
Hey Danke für deine ausführliche Antwort
"So wie hier wäre das Verhalten deiner Beschreibung übrigens ganz ohne
Prozess und ohne signifikante Funktionseinschränkung kürzer beschrieben:
........"
Dann wird die LED aber doch nur ausgeschaltet solange der Taster
gedrückt wurde. Quasi so wie ich es mit den anderen LEDs testweise auch
gemacht habe. Ich wollte ja, dass wenn ich einmal drücke die LED
anbleibt auch wenn ich loslasse, bis ich noch mal drücke.
"BTW:
Dein Prozess oben ist nur auf CLK sensitiv. TASTER(0) ist unnötig.
Als Tipp:
du brauchst in deinem ersten viertel VHDL-Jahr garantiert (!!!!) keine
Variable. Sicher nicht."
Vielen Dank für die Hinweise. Kann ich als blutiger Anfänger gebrauchen!
Hatte das "Gefühl" Variablen könnten manchmal praktisch sein. Warum
sollte man diese nicht verwenden?
Ich hätte dies also besser außerhalb des processes als Signal definiert?
Mit dem Prellen war mit klar. Wollte erstmal die Funktion des
"Speicherns" hinbekommen. Das andere war mir noch zu aufwenig. Danke für
deine Codebeispiele die werde ich morgen mal durchschauen...
Grüße
> Dann wird die LED aber doch nur ausgeschaltet solange der Taster> gedrückt wurde.
Richtig, du willst ja die LED mit jedem Tastendruck toggeln... :-o
Also brauchst du
1. eine zuverlässige Flankenerkennung für den Taster und dann kannst du
2. mit der erkannten Flanke die LED toggeln.
> Hatte das "Gefühl" Variablen könnten manchmal praktisch sein. Warum> sollte man diese nicht verwenden?
Such einfach mal hier im Forum nach dem Stichwort Variable und du
findest allgemein Probleme mit den Dingern, spätestens, wenn sie
Speichernd sein sollen (Zähler, Zustände, Scheiberegister...). Mehr dazu
im Beitrag "Verständnisproblem: Variablen in Prozessen" und im
Beitrag "Re: VHDL - UP / DOWN 3-Bit Zählerproblem" und recht
ausführlich im Beitrag "Variable vs Signal".
Hallo Lothar Miller,
ich habs noch mal versucht und einfach einen kleinen Counter eingebaut
der per Tastendruck umschaltbar hoch oder runter zählen kann.
Wäre Klasse wenn du noch mal drüber schaun könntest ...
Kommentare erwünscht :-D
Sieht zwar stellenweise noch etwas verworren aus, passt aber schon mal
vom Grundkonzept her...
Insbesondere sollte ein gespeichertes Eingangsbit nicht gerade STATE
heißen, State hört sich irgendwie nach mehr an...
Ob es tatsächlich funktionieren kann, sagt dir eine
Verhaltenssimulation.
> process (CLK, STATE)
STATE ist hier unnötig, weil das Ergebnis des Prozesses nur von CLK
abhängt.
Den Teiler für die Sekunde solltest du ausserhalb machen, dann kannst du
das Sekunden-Flag öfeter mal verwenden:;
Hallo,
vielen Dank für deine Mühe und Kommentare. Habe viel gelernt.Verworren
kam mir das auch vor, aber Tagesziel erreicht :-D Werde sicher am
Wochenende noch ein bisschen weiter rumspielen :-D
Funktionieren tut es. Habe ich gleich auf der Hardware ausgeführt. Dann
habe ich mir zum Spaß mal eine Testbench erstellt und mit ModelSIM (die
kostenlose Starter Version) ein bissel rum probiert. Hat zwar etwas
länger gedauert ging aber mit Hilfe des Tutorial von denen recht gut.
Gibt es da irgend ein Schema um eine VHDL Datei wirklich zu testen. Ich
habe einfach mal ein paar Signale rein geschmissen und geschaut, ob das
rauskommt was ich erwarten würde (bzgl Zählrichtung). Es ist ja
anscheinend sehr wichtig zu simulieren.
Gibt es irgendeinen Grund warum du Prozesse ohne sensity list verwendest
? Oder ist das ehr eine Geschmacksfrage?
Nochmals vielen Dank!
balou schrieb:>> Gibt es irgendeinen Grund warum du Prozesse ohne sensity list verwendest> ? Oder ist das ehr eine Geschmacksfrage?
Wenn man keine sensitivity List in getakteten Prozessen hat, kann man
auch keine Signale zu viel oder zu wenig reintun ;)
>> Es ist ja anscheinend sehr wichtig zu simulieren.
Mit einer Verhaltenssimulation kannst du wenigstens mal feststellen, ob
dein Design prinzipiell funktionieren wird. Ob dann noch irgendwelche
Probleme an Taktdomänenübergängen sind, findest du aber erst in der
realen Hardware heraus...
> Wenn man keine sensitivity List in getakteten Prozessen hat, kann man> auch keine Signale zu viel oder zu wenig reintun ;)
Und man schafft es auch nicht, irgendwelche
Quasi-Concurrent-Beschreibungen getaktet aussehen zu lassen. Die
nfolgende Beschreibung wird in der Simulation so aussehen, wie wenn
dataout vom Takt abhinge:
1
process(clk)begin
2
ifrising_edge(clk)then
3
:-- hier passiert jetzt einiges
4
endif;
5
dataout<=datain;-- und dann kommt noch eine ungetaktete Zuweisung
6
endprocess;
Der Synthesizer wird aber einfach eine Verbindung zwischen datain und
dataout machen, und das mit einer Warnung bekanntgeben.
Dieser Prozess dagegen ist komplett getaktet:
1
processbegin
2
waituntilrising_edge(clk);
3
:-- hier passiert jetzt einiges
4
dataout<=datain;-- und dann kommt noch eine getaktete Zuweisung