Forum: FPGA, VHDL & Co. [VHDL] Status speichern


von balou (Gast)


Lesenswert?

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

von user (Gast)


Lesenswert?

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';

von balou (Gast)


Lesenswert?

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

von balou (Gast)


Lesenswert?

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

von Klaus F. (kfalser)


Lesenswert?

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.

von der mechatroniker (Gast)


Lesenswert?

Und einen Taster als Clock verwenden, ist -- gleich ob in einem CPLD, 
FPGA oder ASIC -- mehr als mutig.

von balou (Gast)


Lesenswert?

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

von D. I. (Gast)


Lesenswert?

Man taktet das über ein Schieberegister zu seiner Clockdomäne ein und 
schaut ob ein Wechsel von 0 auf 1 im Schieberegister steht.

von duckundwech (Gast)


Lesenswert?

>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.

von balou (Gast)


Angehängte Dateien:

Lesenswert?

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.
1
process (TASTER(0), CLK)
2
type TASTER_STATE_TYPE is (TASTER_PRESSED, TASTER_RELEASED);
3
variable TASTER_STATE : TASTER_STATE_TYPE := TASTER_RELEASED;
4
begin
5
  if rising_edge(CLK) then
6
    if (TASTER(0) = '0') and (TASTER_STATE = TASTER_RELEASED) then
7
         if (STATE = LED_OFF) then
8
        STATE <= LED_ON;
9
        else
10
        STATE <= LED_OFF;
11
        end if;
12
        TASTER_STATE := TASTER_PRESSED;
13
    elsif (TASTER(0) = '1' and (TASTER_STATE = TASTER_PRESSED)) then
14
        TASTER_STATE := TASTER_RELEASED;
15
    end if;
16
  end if;
17
end process;
18
19
LED(4) <= '0' when (STATE = LED_ON) else '1';

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


Lesenswert?

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) <= not TASTER(0) when rising_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.

von balou (Gast)


Lesenswert?

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

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


Lesenswert?

> 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".

von balou (Gast)


Angehängte Dateien:

Lesenswert?

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

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


Lesenswert?

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:;
1
  process begin -- Vorteiler
2
    wait until rising_edge(CLK);
3
    OneSecond <='0';
4
    if (TIMER_COUNTER = XTAL - 1) then  -- TIMER_COUNTER erzeugt Sek. Takt
5
      TIMER_COUNTER <= 0;
6
      OneSecond <='1';
7
    else
8
      TIMER_COUNTER <= TIMER_COUNTER + 1;
9
    end if;
10
  end process
11
12
  process begin  -- Zähler
13
    wait until rising_edge(CLK);
14
    if OneSecond='1' then
15
      case DIRECTION is
16
      when '0' => 
17
        if (COUNTERX = 63) then -- Überlauf
18
          COUNTERX <= 0;
19
        else
20
          COUNTERX <= COUNTERX + 1;
21
        end if;
22
      when others => 
23
        if (COUNTERX = 0) then -- Überlauf
24
          COUNTERX <= 63;
25
        else
26
          COUNTERX <= COUNTERX - 1;
27
        end if;
28
      end case;
29
    end if;
30
  end process;
31
32
  process begin -- irgendwas anderes, das im Sekundentakt ablaufen soll
33
    wait until rising_edge(CLK);
34
    if OneSecond='1' then
35
       :
36
    end if;
37
  end process;

von balou (Gast)


Lesenswert?

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!

von D. I. (Gast)


Lesenswert?

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 ;)

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


Lesenswert?

>> 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
     if rising_edge(clk) then
3
        : -- hier passiert jetzt einiges
4
     end if;
5
     dataout <= datain; -- und dann kommt noch eine ungetaktete Zuweisung
6
  end process;
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
  process begin
2
     wait until rising_edge(clk);
3
        : -- hier passiert jetzt einiges
4
     dataout <= datain; -- und dann kommt noch eine getaktete Zuweisung
5
  end process;

von balou (Gast)


Lesenswert?

Okay, noch mals vielen Dank

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.