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
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
@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.
@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
@Sven siehste, sowas lernt mal halt nur hier im Forum ;-) ... wenn Leute halt die richtigen Fragen stellen.
##################################################################### 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
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
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.