Forum: FPGA, VHDL & Co. VHDL-Fragen


von Sven (Gast)


Lesenswert?

Hi!
Ich arbeite mich derzeit in der wenigen Freizeit etwas in VHDL ein, und
nutze dafür ein Spartan 3 von Xilinx mit Web ISE.
Wahrscheinlich werden in naher Zukunft daher einige durch andere
Quellen unbeantwortete VHDL-bezogene Fragen auftauchen, die ich gerne
hier im Forum stellen möchte. Ich werde sie dann der Übersichtlichkeit
halber wohl stets in diesem Thread hier stellen.

Zum Beginn eine ganz einfache (?) Frage:

Bei der Strukturbeschreibung muss man ja per component die Komponenten
definieren, z.B. per:

component MYENTITY
port (A : std_logic);
end component MYENTITY;

Meine Frage nun:
Ist das erwähnen der ports an dieser Stelle notwendig?
Ich habe keine Möglichkeit gefunden, die port-list einfach wegzulassen,
so dass bei Instanziierung automatisch die ganz normale Portdefintion
aus der entsprechenden Entity-Beschreibung genutzt wird.
So wie hier müsste man ja stets sämtliche Portlists mehrfach halten und
pflegen (In der Entity- und jeder Component-Definition).

Weiss da jemand eine Antwort ?
Danke!
Sven

von Sven Johannes (Gast)


Lesenswert?

Moin...

Ja, richtig erkannt. Darum gibts auch tools die das automatisieren. Wie
schon mehrfach gesagt, VHDL ist eigentlich viel umfangreicher und
dadurch entsteht dieser Overhead.

--
 Sven Johannes

von FPGA-User (Gast)


Lesenswert?

@Sven

Du musst nicht jedesmal die component-Deklaration hinschreiben,
wenn Du eine Instanz der component in irgendeinem File verwenden
willst.
Es reicht, wenn Du bei der Instanziierung folgendes schreibst
(Beispiel):

   bitcount_1 : entity work.bitcount -- (!)
      port map
      (
         din   => din,
         sum   => sum
      );

Damit sparst Du Dir zumindest das updaten der component-Deklarationen,
falls Du Ports änderst, beim Instanziieren muss die PORT MAP
natürlich überall aktualisiert werden.
Hoffe, dass ich Deine Frage richtig verstanden habe.

von Sven (Gast)


Lesenswert?

@FPGA-User
!Exakt, danke!
Das ist ja sogar noch besser, als leere component-Definitionen, o.ä.
Lösungen.
Seltsam, ich habe das in keiner Quelle finden können. Dort wird immer
nur die 'klassische' Instanziierung nach component-Definitionen
erwähnt. Derzeit nutze ich zum Lernen:

[1] VHDL-Kurzreferenz von A. Mäder:
http://wwwhni.uni-paderborn.de/eps/uni/courses/gti/VHDL/docs/VHDL_Kurzreferenz_Maeder.pdf

[2] VHDL-Cookbook von Peter J. Ashenden:
http://wwwhni.uni-paderborn.de/eps/uni/courses/gti/VHDL/docs/VHDL-Cookbook.pdf

[3] einige kleinere Uni-Tutorials

Diese .pdfs helfen mir schon gut, aber hat vielleicht noch jemand einen
anderen Tipp, möglichst ebenfalls als kostenloses .pdf ?

nochmals gracias,
Sven

von FPGA-User (Gast)


Lesenswert?

@Sven

siehste, sowas lernt mal halt nur hier im Forum ;-)
... wenn Leute halt die richtigen Fragen stellen.

von Sven (Gast)


Lesenswert?

#####################################################################

Ahoi!
Ich bins wieder mit einer weiteren Frage. Diesmal ist es weniger eine
reine VHDL-Syntax-Frage, sondern mehr eine konzeptionelle.

Problem:
Ich baue mir einen Getränkeautomaten. Mit dem Drücken einer seiner
Tasten soll eine Aktion ausgelöst werden (Zustandsveränderung). Dies
soll aber nur einmalig zum Zeitpunkt des Drückens der Taste geschehen,
danach soll die noch gedrückte Taste ignoriert werden, bis sie
losgelassen wurde.

Das einfachste wäre - dachte ich - einen Prozess zu nehmen, und dem in
seine Sensitivliste die Eingangssignale der Tasten zu geben:

        stateLogic : process (RST, EUROEINWURF, WAHLCOLA, WAHLBRUEHE,
GELDZURUECK)

So dass in einem späteren langen if-Zweig nur noch die steigende Flanke
der einzelnen Signale abgefragen werden muss:

        if (RST='1' and RST'Event) then
          -- resette
        elsif (EUROEINWURF='1' and EUROEINWURF'Event) then
          -- behandle Einwurf eines Euros
        elsif (WAHLCOLA='1' and WAHLCOLA'Event) then
          -- behandle das Drücken der Colataste
        ...
        end if;

In den jeweiligen if-Zweigen wird jedesmal u.a. das Signal nextState
neu belegt. Aber Pustekuchen, dieser Code schmeißt eine Fehlermeldung:
"bad synchronous description."
Einiges Nachlesen auf den Xilinx-Seiten zeigte, dass man innerhalb
eines Prozesses nur einmalig 'Event nutzen darf.

'wait for' bzw. 'wait until' kann man noch schlechter und
eingeschränkter als 'Event nutzen, so dass es hier ebenfalls nicht
weiterführt.

Meine Frage nun ist, wie ich dieses Verhalten nun am Sinnvollsten
entwerfen kann ?

Als Lösung fiel mir bisher ein, einfach ein internes Signal:

        signal waitArray : std_logic_vector (0 to 3)

zu nutzen, welches an seinen Bitpositionen den gegenwärtigen
Signalzustand der jeweiligen Eingänge speichert. Dann kann man das
gewünschte Verhalten auf folgende Art und Weise erzielen:

        stateLogic : process (RST, EUROEINWURF, WAHLCOLA, WAHLBRUEHE,
GELDZURUECK) is
          begin
            if (RST = '1' and waitArray = "00000") then
              nextState <= NONE;
              waitArray(0) <= '1';
            elsif (RST='0' and waitArray(0) = '1') then
              waitArray(0) <= '0';
            elsif (EUROEINWURF = '1' and waitArray = "00000") then
              -- ............
              waitArray(1) <= '1';
            elsif (EUROEINWURF='0' and waitArray(1) = '1') then
              waitArray(1) <= '0';
            elsif (WAHLCOLA = '1' and waitArray = "00000") then
              -- ............
              waitArray(2) <= '1';
            elsif (WAHLCOLA='0' and waitArray(2) = '1') then
              waitArray(2) <= '0';
            elsif .......
                ....
            end if;
        end process;

Auf diese Weise funktioniert es. Ich nutze also das waitArray() damit
als eine Art Sperrflag.
Geht das aber nicht auch einfacher ?
Sollte ich vielleicht gar keinen Prozess nehmen ?

Danke fürs Lesen und ggf. Antworten.
Bye,
Sven

von FPGA-User (Gast)


Lesenswert?

Hallo Sven,

bei Deiner Anwendung würde ich folgendes machen:

1.) einen sinnvollen Systemtakt wählen, dieser ist die Basis
für Dein gesamtes Design

2.) Die Signale von den Tasten mit diesem Clock einlesen, evt.
noch ein Clock-Enable spendieren, denn die Tasten sind für ein
FPGA eine relativ "langsame" Quelle und man muss ja nicht mit 10MHz
oder so pollen

3.) Eine FSM, die folgendes macht:
- prüfen, ob eine Taste gedrückt ist,
- falls ja -> eine best. Prellzeit abwarten (Wait-State)
- die gedrückte Taste merken und eine entspr. Aktion auslösen
- evt. warten, bis die gedrückte Taste losgelassen wurde
- dann geht die FSM wieder in den Start-State

von Sven (Gast)


Lesenswert?

Hallo!
Dann scheint wohl der grundlegende Unterschied zu sein, dass in deinem
Modell die Tasten synchron im Takt nach ihrem Zustand abgefragt werden,
während in meinem ursprünglichen Vorgehen die Tasten einfach irgendwann
asynchron zwischendurch ein Event auslösen können.

Ist das beim HW-Design normal, dass man Inputs, die 'langsam genug'
sind, synchron zu einem Takt nach ihrem Zustand abfragt ?
Ich dachte, es sei vielleicht eher so, dass man versucht, so viel wie
möglich asynchron zu halten. Quasi eine 'event-driven-architecture',
wie sie auch gerne im Softwarebereich genutzt wird.

von FPGA-User (Gast)


Lesenswert?

Hallo,

kommt drauf an, wie Du asynchron definierst. Man kann natürlich
auch rein kombinatorisch im FPGA arbeiten, aber Deine Steuerung
schreit ja geradezu nach einem "Zustandsautomaten", der braucht
nun einen Takt.
Und wenn man schon mit einem Takt arbeitet, dann möglichst synchron,
also auch die Tasten ändern sich FPGA-intern nur mit dem Takt.
Wie Du dann auf ein Tasten-Signal reagierst, ist Deiner
Kreativität überlassen. Aber eine Statemachine ist aus meiner
Sicht ideal dafür.
Von der Software-Denkweise sollte man sich zumindest am Anfang
beim FPGA lösen, sonst kommt man m.E. durcheinander.

von m.mue (Gast)


Lesenswert?

Hallo,

ich kann dem FPGA-User nur zustimmen: Zuerst solltest Du Dich von dem
Software-Denken lösen. Versuch in FlipFlops oder Registern zu denken,
immerhin programmierst Du hier Hardware. Ein VHDL-Programm wird nicht
wie in der "reinen" Software nacheinander ausgeführt, sondern
parallel. "Ausnahme" bilden hier die Prozesse, deren Anweisungen
nacheinander ausgeführt werden, aber auch nur, weil diese entsprechend
synthetisiert sind. !!! Wichtig: Signale die in einem Prozess verändert
werden, werden erst an dessen Ende aktualisiert. Die neuen Werte können
also nicht in der folgenden Zeile schon wieder verwendet werden. Das
geht wiederum nur mit Variablen !!! (ich hoffe ich hab Dich jetzt nicht
erschlagen)

Dann empfehle ich Dir, Dich vorher mit Zustandsautomaten (state
machine, FSM) zu beschäftigen. (Solltest Du das schon getan haben, dann
vergiss diesen Absatz) Diese sind eigentlich Lösung für FAST jedes
Problem, bei dem die gleichen Eingangssignale verschiedene Reaktionen
hervorrufen sollen. (Eben in Abhängigkeit des Zustandes des Automaten)
... tut mir Leid, im Moment kann ich gar keinen Link empfehlen. Am
besten einfach mal googlen.

Dein beschriebenes Problem, auf den Taster zu reagieren, kannst Du auf
verschiedene Art und Weisen lösen:

1. Einen Impuls erzeugen, der auf die fallende oder steigende Flanke
des Eingangssignal reagiert. Dies geht mit einem D-Flipflop, welches
das Signal um einen Takt verzögert. Nun erfolgt eine UND-Verknüpfung
des originalen Signals mit dem Verzögerten. !!! Je nach dem welches
Signal vor der UND-Verknüpfung invertiert wird, erhälst Du einen Impuls
bei der steigenden Flanke (verzögertes Signal invertiert) oder bei der
fallenden Flanke (originales Signal invertiert)

!!! Hierbei muss der Taster entprellt sein.

2. Du reagierst mit der FSM auf den Eingang. Ein Zustand Z0 wartet bis
dieser High ist, woraufhin die FSM in den Zustand Z1 übergeht. Jetzt
hast Du die Möglichkeit Z1 erst denn wieder zu verlassen, wenn Dein
Eingang Low ist (Taster entprellen !!!) oder Z1 reagiert gar nicht auf
den Eingang sondern auf ein anderes Signal. In diesem Fall müsste der
Taster nicht einmal entprellt werden.


Und zum Schluss: Jedes asynchrone Eingangssignal sollte man wegen
"möglicher instabiler" Zustände über zwei FlipFlop-Stufen eintakten.

m.mue

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.