mikrocontroller.net

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


Autor: balou (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: user (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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';

Autor: balou (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: balou (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: der mechatroniker (Gast)
Datum:

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

Autor: balou (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: D. I. (Gast)
Datum:

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

Autor: duckundwech (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: balou (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

process (TASTER(0), CLK)
type TASTER_STATE_TYPE is (TASTER_PRESSED, TASTER_RELEASED);
variable TASTER_STATE : TASTER_STATE_TYPE := TASTER_RELEASED;
begin
  if rising_edge(CLK) then
    if (TASTER(0) = '0') and (TASTER_STATE = TASTER_RELEASED) then
         if (STATE = LED_OFF) then
        STATE <= LED_ON;
        else
        STATE <= LED_OFF;
        end if;
        TASTER_STATE := TASTER_PRESSED;
    elsif (TASTER(0) = '1' and (TASTER_STATE = TASTER_PRESSED)) then
        TASTER_STATE := TASTER_RELEASED;
    end if;
  end if;
end process;

LED(4) <= '0' when (STATE = LED_ON) else '1';

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
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.

Autor: balou (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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".

Autor: balou (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:;
  process begin -- Vorteiler
    wait until rising_edge(CLK);
    OneSecond <='0';
    if (TIMER_COUNTER = XTAL - 1) then  -- TIMER_COUNTER erzeugt Sek. Takt
      TIMER_COUNTER <= 0;
      OneSecond <='1';
    else
      TIMER_COUNTER <= TIMER_COUNTER + 1;
    end if;
  end process

  process begin  -- Zähler
    wait until rising_edge(CLK);
    if OneSecond='1' then
      case DIRECTION is
      when '0' => 
        if (COUNTERX = 63) then -- Überlauf
          COUNTERX <= 0;
        else
          COUNTERX <= COUNTERX + 1;
        end if;
      when others => 
        if (COUNTERX = 0) then -- Überlauf
          COUNTERX <= 63;
        else
          COUNTERX <= COUNTERX - 1;
        end if;
      end case;
    end if;
  end process;

  process begin -- irgendwas anderes, das im Sekundentakt ablaufen soll
    wait until rising_edge(CLK);
    if OneSecond='1' then
       :
    end if;
  end process;

Autor: balou (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: D. I. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

Autor: balou (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, noch mals vielen Dank

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.