Tag Zusammen, ich(VHDL Neuling) versuche gerade einen Automaten zu schreiben, der 4 Zustände annehmen soll. Solange kein reset anliegt, sollen die Zustanände A_Auslesen, B_Auslesen. C_Auslesen, A_Auslesen,... der Reihe nach ausgeführt werden. Da es verschiedene Arten von Automaten gibt, möchte ich wissen, ob dieser Automat so voll funktionsfähig ist. Meine zweite Frage wäre: Wie kann ich DIESEN Automaten im Zustand A_Auslesen starten, wenn ich meine Schaltung mit Strom versorge? Die Aufgabe des Automaten ist es, 3x8 Bit aus einem UART-Modul auszulesen und diese einem nachfolgenden Auswertemodul zur Verfügung zu stellen (Signal Daten_abholen_out="1"). Kann sich jemand dies bitte mal anschauen und mir mögliche Fehler in diesem Automaten nennen? Habe noch Probleme damit :( Danke!
Es gibt auch andere Wege aus einem UART-Modul 3 Bytes auszulesen, auch wenn dieser nur 1Byte am Stück auslesen kann. Hierfür brauchst du keinen Automaten, sondern ein Register und einen Zähler.
Danke. Ich bin überzeugt, dass es verschiedene Lösungswege gibt. Wäre ich so gut in VHDL könnte ich mir selber ein paar Sachen einfallen lassen. DOch kann ich meine Modelle nicht in die praxis umsetzen, mangels Kenntisse :( Ich würde mich sehr freuen, wenn Ihr zu euren Lösungswegen einen Code-Schnipsel posten würdet oder meine State-Machine euch anschauen würdet. Vielen Dank
Hallo nochmals, ich habe ein paar Fehler herausgefiltert. Leider komme ich aber nicht mehr weiter. LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_signed.ALL; --------------------------------------------------------------------- --- ENTITY Deklaration des Automaten --------------------------------------------------------------------- entity DATEN_AUSLESEN is port ( CLK : in std_logic; -- Takt Daten_abholen_in: in std_logic; -- Signalisiert das Vorhandensein neuer Daten Data_In_8 : in std_logic_vector(7 downto 0); -- Eingangsdaten aus Receiver-Modul Reset : in std_logic; -- Resetsignal für Automat(Zustand=Idle) Flag : out std_logic; -- Daten abgeholt --> Receiver resetten für neue Daten Data_Out_24 : out std_logic_vector(23 downto 0); -- 3x8 Bit a Daten Daten_abholen_out: out std_logic ); end entity DATEN_AUSLESEN; ------------------------------------------------------------------- -- ARCHITECTURE Beschreibung des Automaten ------------------------------------------------------------------- architecture DATEN_AUSLESEN_ARCH of DATEN_AUSLESEN is -- States definieren type Zustaende is (IDLE, A_AUSLESEN, B_AUSLESEN, C_AUSLESEN); attribute enum_encoding : string; attribute enum_encoding of Zustaende: type is "00, 01, 10, 11"; Signal Aktueller_Zustand : Zustaende; Signal A :std_logic_vector(7 downto 0); Signal B :std_logic_vector(7 downto 0); Signal C :std_logic_vector(7 downto 0); begin ------------------------------------------------------------------- -- Ermittlung des neuen Zustandes ------------------------------------------------------------------- Zustandsfolge : PROCESS( Daten_Abholen_In, Reset ) begin if Reset ='1' then Aktueller_Zustand<=IDLE; elsif rising_edge(Daten_Abholen_In) then CASE Aktueller_Zustand IS WHEN A_AUSLESEN => Aktueller_Zustand <= B_AUSLESEN; WHEN B_AUSLESEN => Aktueller_Zustand <= C_AUSLESEN; WHEN C_AUSLESEN => Aktueller_Zustand <= A_AUSLESEN; WHEN IDLE => Aktueller_Zustand <= A_AUSLESEN; END CASE; END IF; END PROCESS; -------------------------------------------------------- -- Berechnung der Ausgänge ------------------------------------------------------- OUTPUT: Process (Aktueller_Zustand) begin CASE Aktueller_Zustand is WHEN IDLE => A<="00000000"; B<="00000000"; C<="00000000"; Flag<='0'; Daten_abholen_out<= '0'; WHEN A_AUSLESEN => A<=Data_In_8; Flag<='1'; Daten_abholen_out<= '0'; WHEN B_AUSLESEN => B<=Data_In_8; Flag<='1'; Daten_abholen_out<= '0'; WHEN C_AUSLESEN => C<=Data_In_8; Flag<='1'; Daten_abholen_out<= '1'; End CASE; END Process; END DATEN_AUSLESEN_ARCH;
Hallo nochmals! Ich habe versucht durch google weitere Foren zu finden, die sich auch mit VHDL befassen und so belebt wie dieser sind. Leider habe ich keine ähnlichen gefunden. Hat einer von euch zufällig ein ähnliches Forum entdckt auch in englischer Sprache? Wenn ja, könnt ihr die Adresse posten? Thanks!
Hallo Leute, ich würde gerne wissen, wie eine Frage aussehen muss, damit auf diese eine Antwort erfolgen kann. Kann es sein, dass ich zu banale Fragen stelle, auf die niemand antworten möchte? Ich würde nicht in dieses Forum schreiben, wenn ich weiss, dass auf VHDL-spezifische Fragen keine Antworten erfolgen. Und diese würde ich nicht stellen, wenn ich selber eine Antwort drauf parat hätte... {Kommentar eines Verzweifelten :( } Schönen Tag!
@vhdl_beginner >Kann es sein, dass ich zu banale Fragen stelle, auf die niemand >antworten möchte? Es ist manchmal hilfreich die Fragen zu nummerieren. So kann man auch gezielt und schnell darauf Antworten. Ich versuche mal die Fragen zu beantworten: (1) >Da es verschiedene Arten von Automaten gibt, möchte ich wissen, ob >dieser Automat so voll funktionsfähig ist. Nein (2) >Meine zweite Frage wäre: Wie kann ich DIESEN Automaten im Zustand >A_Auslesen starten, wenn ich meine Schaltung mit Strom versorge? Indem du im asynchronen Reset dem signal "Zustand" den Wert A_Auslesen zuweist. (3) >Ich würde mich sehr freuen, wenn Ihr zu euren Lösungswegen einen >Code-Schnipsel posten würdet oder meine State-Machine euch anschauen >würdet. Dieser Automat ist in dieser Form nicht funktionsfähig. Eine Überarbeitung würde mehr Zeit kosten als ihn komplett neu zu schreiben. Du versuchst eine Art Mix aus Ein- und Zweiprozess- Zustandsautomat zu schreiben. Hier mal ein Beispiel an dem du dich orientieren kannst. Eingangssignale: sig1_i,sig2_i,clock,reset Ausgangssignale: sig1_o,sig2_o type state_type is (IDLE,S1,S2) signal state_reg,next_state; signal temp_reg,next_temp; process (clock) is begin if(rising_edge(clock) then if(reset = '1') then state_reg <= next_state; else state_reg <= next_state; temp_reg <= next_temp; end if; end if; end process; process (state_reg,sig1_i,sig2_i,temp_reg) is begin next_temp <= temp_reg; next_state <= state_reg; sig1_o <= '0'; sig2_o <= '0'; case state_reg is when IDLE => if(sig1_i = '1') then next_state <= s1; end if; when s1 => sig1_o <= '1'; if(sig2_i = '1') then sig2_o <= temp_reg; next_state <= s2; end if; when s2 => if(sig2_i = '1') then next_temp <= '1'; end if; next_state <= IDLE; when others => next_state <= idle; end case; end process; Versuch mal das ganze in dieser oder ähnlicher Form zu schreiben. Ich glaube dann wird man auch in diesem Forum schnell zu einer funktionsfähigen Lösung kommen. Mein Lösungsansatz wäre: 4 Zustände (IDLE,WR1,WR2,WR3,OUTPUT) ein 24 Bit Register in dem die Daten von der UART aufgenommen werden. Urzustand nach reset: IDLE danach sofortiger Übergang zu WR1 WR1,WR2,WR3: Zustände in denen das 24 Bit Register gefüllt wird. Zustand OUTPUT auslesen des 24 Bit Registers mit Handshake. Gruß Tobias Die einzige "Frage" die ich aus deinem ersten Posting extrahieren konnte war: >Kann sich jemand dies bitte mal anschauen und mir mögliche Fehler in >diesem Automaten nennen? Habe noch Probleme damit :( In meinen Augen ist das auch keine Frage sondern eine Bitte sich mal den VHDL Text anzusehen und auf Fehler zu überprüfen. Jetzt zu deiner "Frage" von deinem zweiten Posting. >Ich würde mich sehr freuen, wenn Ihr zu euren Lösungswegen einen >Code-Schnipsel posten würdet oder meine State-Machine euch anschauen >würdet. Na klar mach ich doch gerne. In deinem Code benutzt du für den Zustandsübergang das Signal Daten_Abholen_In und bestimmst in dem Prozess auch noch den Folgezustand. Für getaktete Prozesse benutze für die Zustandszuweisung das Taktsignal "clk". CLK sowie Data_Out_24 wird überhaupt nicht benutzt. entity DATEN_AUSLESEN is port ( CLK : in std_logic; -- Takt Daten_abholen_in : in std_logic; Data_In_8 : in std_logic_vector(7 downto 0); -- Reset : in std_logic; Flag : out std_logic; -- Daten abgeholt --> Data_Out_24 : out std_logic_vector(23 downto 0); -- 3x8 Bit a Daten_abholen_out: out std_logic ); end entity DATEN_AUSLESEN;
Ein bisschen zuviel geschickt. Der untere Teil gehört nicht mehr zum Posting Gruß Tobias
Hi, ich habe an meiner FSM weitergearbeitet, Trotz mehrerer Änderungen bekomme ich Sie dennoch nicht sauber zum Laufen. Kann bitte hier jemand mal einen Blick reinwerfen und mir sagen, was hier falsch läuft, bzw. wie es aussehen müsste? Danke! LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_signed.ALL; --------------------------------------------------------------------- --- ENTITY Deklaration des Automaten --------------------------------------------------------------------- entity DATEN_AUSLESEN is port ( Clk : in std_logic; -- Takt Daten_abholen_in: in std_logic; -- Signalisiert das Vorhandensein neuer Daten Data_In_8 : in std_logic_vector(7 downto 0); -- Eingangsdaten aus Receiver-Modul Reset : in std_logic; -- Resetsignal für Automat(Zustand=Idle) Flag : out std_logic; -- Daten abgeholt --> Receiver resetten für neue Daten Data_Out_24 : out std_logic_vector(23 downto 0); -- 3x8 Bit a Daten Daten_abholen_out: out std_logic ); end DATEN_AUSLESEN; ------------------------------------------------------------------- -- ARCHITECTURE Beschreibung des Automaten ------------------------------------------------------------------- architecture ARCH of DATEN_AUSLESEN is -- States definieren type Zustaende is (IDLE, A_AUSLESEN, B_AUSLESEN, C_AUSLESEN); Signal Naechster_Zustand : Zustaende; Signal A,B,C :std_logic_vector(7 downto 0); begin ------------------------------------------------------------------- -- Ermittlung des neuen Zustandes ------------------------------------------------------------------- Zustandsfolge : PROCESS( Daten_Abholen_In, Reset, Clk ) begin if (Reset ='0') then Naechster_Zustand<=IDLE; elsif rising_edge(Daten_Abholen_In) then CASE Naechster_Zustand IS WHEN IDLE => Naechster_Zustand <= A_AUSLESEN; WHEN A_AUSLESEN => Naechster_Zustand <= B_AUSLESEN; WHEN B_AUSLESEN => Naechster_Zustand <= C_AUSLESEN; WHEN C_AUSLESEN => Naechster_Zustand <= A_AUSLESEN; WHEN others => Naechster_Zustand <= IDLE; END CASE; END IF; END PROCESS; -------------------------------------------------------- -- Berechnung der Ausgänge ------------------------------------------------------- OUTPUT: Process (Naechster_Zustand) begin CASE Naechster_Zustand is WHEN IDLE => A<="00000000"; B<="00000000"; C<="00000000"; Flag<='0'; Daten_abholen_out<= '0'; WHEN A_AUSLESEN => A<=Data_In_8; Flag<='1'; Daten_abholen_out<= '0'; WHEN B_AUSLESEN => B<=Data_In_8; Flag<='1'; Daten_abholen_out<= '0'; WHEN C_AUSLESEN => C<=Data_In_8; Flag<='1'; Daten_abholen_out<= '1'; End CASE; END Process; END ARCH;
Zwei Punkte: 1. Alles was getaktet wird (d.h. alles was Flip-Flops darstellt), sollte mit dem Systemtakt (clk) getaktet werden. Du nimmst aber "Daten_Abholen_In" als Takt für Deinen Automaten. Benutze dieses Signal als Taktfreigabesignal: elsif rising_edge(clk) then if(Daten_Abholen_In = '1') then -- blabla end if; end if; Dann musst Du aber sicherstellen dass "Daten_Abholen_In" auch nur für einen clk-Zyklus auf '1' ist. 2. Der zweite Prozess beschreibt Latches (= pegelgesteuerte Flip-Flops). Ich bezweifle dass Du das willst. Falls die Signale die dort vorkommen rein kombinatorische Logik darstellen sollen, musst Du jedem Signal auch in jedem when-Abschnitt auch etwas zuweisen. Falls Du Flip-Flops daraus machen willst, musst Du das ganze in einen "if rising_edge(clk)"-Block einbetten.
Leider ist das Daten_Abholen_In so lange auf High, bis ich diesen mit dieser State-Machine auf Low setze, d.h mit Flag=1 wird es wieder asynchron resettet. Daten_Abholen_In geht auf High, wenn Daten zum Abholen bereitstehen. Damit man weitere Daten erwarten und abholen kann, muss der Automat, der dieses Signal(Daten_Abholen_In) steuert resettet werden
Du kannst aus jedem Signal das längere Zeit auf '1' liegt eins machen, das für einen clk-Zyklus auf '1' liegt. Das ist sozusagen eine Standard-Problem. Dafür machst Du Dir einfach eine zweiten Automaten: --------------------------------------------------- process(reset,clk) begin if(reset = '0') then state <= s0; elsif(rising_edge(clk)) then case state is when s0 => if(Daten_Abholen_In = '0') then state <= s1; end if; when s1 => if(Daten_Abholen_In = '1') then state <= s2; end if; when s2 => state <= s0; end case; end if; end process; --------------------------------------------------- sig_one <= '1' when (state = s2) else '0'; --------------------------------------------------- Anstatt "Daten_Abholen_In" kannst Du jetzt "sig_one" als Taktfreigabe benutzen.
Das halte ich für keine gute Idee. Besser ist es, die Signale gleich bei ihrer "Entstehung" so zu generieren, dass sie nur einen Takt lang high sind. Das dürfte kein Problem sein, kostet weniger Resourcen und ist einfacher. Daniel
Da hast du ja vollkommen Recht damit, aber ich verwende ein fertiges Core, welches mir leider ein Signall, dass mehrere Takte lang ist bereitstellt. Es würde viel mehr Zeit und Arbeit kosten, dieses Core zu ändern, anstelle ein neues zu designen. Ich weiss aber immer noch nicht so recht, ob mir weitere Arbeiten mit dem alten Core auch bei den nächsten Programmschritten Schwierigkeiten bereiten würden. Muss diese mal klarstellen. Resourcen sind zur Zeit das kleinste Problem.
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.