Hallo zusammen! Ich habe wieder ein Problem mit einem Zustandsautomat.Ein zustand will ich als eine 30 ns Taktverzögerung verwenden.Das heisst ich muss die zahl 3 da definieren und mit jedem clock(100 MHz)wird der zahl dekrementiert(!=0=>im aktuellen zustand bleiben) wenn ich die Null erreiche, dann kann ich zum nächsten zustand springen.Aber das programm macht total was anders sogar kann es die zahl auch nicht dekrementieren.Ich haoffe dass jemand mir bei diesem Problem helfen könnte.)ISE webpack(9.2i & 10.1). MFG
@VHDL_Bginner es wäre hilfreich, wenn Du den VHDL-Code mal posten würdest, oder willst Du gleich die fertige Lösung von jemand anders haben?
MARK!Es ist nett von Dir,dass du schnell darauf antwortest.Ich denke mein problem habe ich richtig beschrieben und wenn man sorgar keine Ahnung in VHDL kann er es verstehen denke ich mal.Das Problem haengt nicht davon ab wie man es in VHDL schreiben kann,Aber meine frage ist sowas in Hardware realisierbar. Und hier ein code stück extra für Dich für 2 zustände aber die frage für Alle selbsverständlich: begin : signal counter:std_logic_vector(2 downto 0):="000"; Eins:process(clk) --Aktualisierung begin : if rising_edge(clk) then State_nxt<=S0; end if; end process(Eins); zweitens;process(zustand) begin case zustand is when s0 => state_nxt<=s1; --counter ist schon initialisiert when s1 => counter<=counter+1;-- hier ist eine Inkrementierung) if counter<4 then --wieso counter zaehlt nicht hoch? state_nxt<=s1;--wenn ich ein extra zustand definiere wird end if; --inkrementiert aber wenn ich so definiere --macht er gar nichts else state_nxt<=s0; end case; end process zweitens; : Für jede Hilfe bin ich sehr Dankbar. MFG
sorry!ich habe mich vertippt.im ersten prozess statt state_nxt<=s0 muss state_current<=state_nxt sein.
Bau Dir eine Testbench dazu und teste das im Simulator! Außerdem mußt Du dafür sorgen, das Dein counter auch mal wieder zurückgesetzt wird. Rick
Eine Möglichkeit währe z.B.: es wird nun jeder State um 3 Takte verzögert, ich habe allerdings die Statemachine hier in if else ausgeführt, das geht auch mir switch und mit Signalen. Ich bin selbst allerdings Anfänger (VHDL) und würde mich über kommentare der VHDL Cracks freuen ! Gruß Joachim library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity FSM is Port ( RESET : IN std_logic; CLK : IN std_logic; OUTPUT : OUT std_logic_vector(3 downto 0) ); end FSM; architecture Behavioral of FSM is begin process (RESET,CLK) variable count : integer range 0 to 2; variable zustand : integer range 0 to 3; begin if RESET = '1' then count := 0; elsif rising_edge(CLK) then count := count +1; if count > 2 then count := 0; if zustand = 0 then OUTPUT <= "0001"; zustand := zustand + 1; elsif zustand = 1 then OUTPUT <= "0010"; zustand := zustand + 1; elsif zustand = 2 then OUTPUT <= "0100"; zustand := zustand + 1; elsif zustand = 3 then OUTPUT <= "1000"; zustand := 0; end if; end if; end if; end process; end Behavioral;
Hallo Joachim.Aber was Du da geschrieben hast ist ein 3 takt verzögerung für jeden zustand aber das will ich nicht.Mein problem liegt darin,dass Du 3 states hast nehmen wir an!und in einem einzelnen State willst du eine verzögerung von 40 ns Z.B(clock 100MHz).Also in einem zustand musst Du ein defaultwert definieren fuer dein Counter und je nachdem wie Du den zähler zählen(ink. oder dekr.) willst .Counter hat den max oder min wert nicht erreicht bleibt in demselben zustand(UND HIER IST MEIN PROBLEM)sonst naechsten zustand wird erreicht.
Hallo again!Hier ist ein source code Beispiel mit einem Testbench der mein problem zeigt.Cout ist als counter Pin für die Visualisierung.Aber bei der simulation kriege ich kein counter inkrementierung.
@neuling1 da das offensichtlich nicht Dein richtiger Code ist, denn er ist absolut nicht synthesefähig, können wir Dir bei Deinem Problem auch nur schlecht weiterhelfen. Der Fehler kann nahezu überall liegen. es geht los mit syntaxfehlern, fehlenden Signalen in der sensitivity list oder ähnlichem. Prinzipiell ist es recht leicht möglich, sowas zu realisieren...
Du hast recht:-)sorry aber hier ist der richtige Code:Diese Problem hat mich richtig geärgert. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity TEST is port(clk:in std_logic; sort:out std_logic; Cout:out std_logic_vector(2 downto 0) ); end TEST; architecture Behavioral of TEST is type zustaende is (s0,s1); signal zustand:zustaende:=s0; signal folge:zustaende:=s0; signal counter:std_logic_vector(2 downto 0):="000"; begin erstens:process(clk) begin if rising_edge(clk) then zustand<=folge; end if; end process erstens; zweitens:process(zustand) begin case zustand is when s0 => folge<= s1; when s1 => counter<=counter+1; if counter<3 then folge<=s1; Cout<=counter; else folge<=s0; counter<=(others=>'0'); end if; end case; end process zweitens; Drittens:process(zustand) begin case zustand is when s0 => sort<='0'; when others => sort<='1'; end case; end process Drittens; end Behavioral;
@Neuling_1 Was für ein Code und welche Testbench gehört zu der Waveform?
Hier ist die Code + Testbench library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity TEST is port(clk:in std_logic; sort:out std_logic; Cout:out std_logic_vector(2 downto 0) ); end TEST; architecture Behavioral of TEST is type zustaende is (s0,s1); signal zustand:zustaende:=s0; signal folge:zustaende:=s0; signal counter:std_logic_vector(2 downto 0):="000"; begin erstens:process(clk) begin if rising_edge(clk) then zustand<=folge; end if; end process erstens; zweitens:process(zustand) begin case zustand is when s0 => folge<= s1; when s1 => counter<=counter+1; if counter<3 then folge<=s1; Cout<=counter; else folge<=s0; counter<=(others=>'0'); end if; end case; end process zweitens; Drittens:process(zustand) begin case zustand is when s0 => sort<='0'; when others => sort<='1'; end case; end process Drittens; end Behavioral;
Sowas:
1 | :
|
2 | counter<=counter+1; |
3 | :
|
darf nur in einem getakteten Prozess stehen. Sonst gibt das eine kombinatorische Schleife. In deinem Fall hat der Simulator Glück und reagiert nicht mehr auf eine Änderung von counter, weil der nämlich in der sensitivity-list fehlt. Wenn du den korrekterweise einfügst
1 | :
|
2 | zweitens:process(zustand,counter) |
3 | :
|
dann hängt der Simulator sich genauso auf wie deine Hardware. Also: Zähler immer taktabhängig.
Ich bevorzuge die Ein-Prozess-Statemachine. Deine Aufgabe sieht dann so aus:
1 | if rising_edge(clk) then |
2 | case zustand is |
3 | when s0 => zustand <= s1; |
4 | sort <= '0'; |
5 | when s1 => counter <= counter+1; |
6 | if (counter<3) then |
7 | zustand <= s1; |
8 | Cout <= counter; -- Fehler? Cout wird nur hier aktualisiert!! |
9 | else
|
10 | zustand <= s0; |
11 | counter <= (others=>'0'); |
12 | end if; |
13 | sort <= '1'; |
14 | when others ; -- könnte hier stehen |
15 | end case; |
16 | end process; |
Hier steht nur der Clock in der Sensitivity-List. Ist irgendwie lesbarer als die Zwei- oder gar Drei-Prozess-Schreibweise. Man muß sich nur daran gewöhnen, dass sich hier irgendwo ein Takt Latency einschleichen könnte, aber Denken hält jung. Alternativ könnte ich Schreiben:
1 | if rising_edge(clk) then |
2 | case zustand is |
3 | when s0 => zustand <= s1; |
4 | when s1 => counter <= counter+1; |
5 | if (counter=3) then |
6 | zustand <= s0; |
7 | counter <= (others=>'0'); |
8 | end if; |
9 | end case; |
10 | end process; |
11 | |
12 | -- concurrent Zuweisungen
|
13 | Cout <= counter; |
14 | sort <= '0' when zustand=s0 else '1'; |
Danke schön für Deine Antwort.Du hast die ein prozessdarstellung verwendet.meine Frage:ist es nicht realisierbar wenn ich die 3 prozess darstellung benutze.IN dieser darstellung hab ich ein prozess für zustandsregister und zweiter für zustandübergänge und dritter für die Augänge.Bis jetzt ich weiss nicht woran liegt mein Fehler.In meinem Code werd ich mein state S1 natürlich mit einem positiven flanke erreichen und wenn ich drin bin muss counter inkrementiert werden. Also brauche ich keine zusätzliche takte für die Anweisungen was ich drin im meinem zustand definiert habe.(Device ist cpld coolrunnerII).
@Neuling_1 Du hast ein Verständnisproblem. Zur Vereinfachung: ein Counter hat mehrere stabile Zustände und ist daher eine State-Machine (und umgekehrt). Wenn du aber für eine State-Machine einen getakteten Prozess für die Übernahme des Folgezustands brauchst, dann brauchst du auch für das Weiterschalten des Counters einen getakteten Prozess. Ins Unreine geschrieben könnte das evtl. so aussehen:
1 | erstens:process(clk) begin |
2 | if rising_edge(clk) then |
3 | zustand <= folge; |
4 | if(zustand=S1) counter <= counter+1; |
5 | else counter <= (others=>'0'); |
6 | end if; |
7 | end if; |
8 | end process erstens; |
9 | |
10 | zweitens:process(zustand, COUNTER) begin -- ALLE Signale in die Sensitivity-List!!!!!!! |
11 | case zustand is |
12 | when s0 => folge <= s1; |
13 | when s1 => if (counter<3) then |
14 | folge <= s1; |
15 | Cout <= counter; -- soll das so sein?? |
16 | else
|
17 | folge <= s0; |
18 | end if; |
19 | end case; |
20 | end process zweitens; |
21 | |
22 | Drittens:process(zustand) begin |
23 | case zustand is |
24 | when s0 => sort<='0'; |
25 | when others => sort<='1'; |
26 | end case; |
27 | end process Drittens; |
Aber ehrlich gesagt: ein halbes Jahr später würde (selbst) ich (selbst) das nicht mehr kapieren!!!!
Weshalb möchtest Du denn 3 Prozesse ? Kannst Du das Problem Beschreiben ohne deine eigenen Lösungsansätze in Spiel zu bringen? So ganz Verstanden hab ich ja nicht was Du vorhast, aber eine Statemachine in der ein Zustand um n Takt Counts verzögert wird, das ist auch so machbar: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity stateTest2 is Port ( RESET : IN std_logic; CLK : IN std_logic; OUTPUT2 : OUT std_logic_vector(3 downto 0) ); end stateTest2; architecture Behavioral of stateTest2 is type zustaende is (s0,s1); signal zustand:zustaende:=s0; begin process (RESET,CLK) variable count : integer range 0 to 2; begin if RESET = '1' then count := 0; zustand <= s0; elsif rising_edge(CLK) then case zustand is when s0 => OUTPUT2 <= conv_std_logic_vector(count,4); count := count +1; if count > 2 then count := 0; zustand <= s1; else -- mach irgend etwas end if; when s1 => OUTPUT2 <=conv_std_logic_vector(count,4); zustand <=s0; end case; end if; end process; end Behavioral;
@ Joachim Schäfer Ja, jetzt aber auch, wo kommt denn jetzt auf einmal der Reset her? Als kleine Gedankenstütze: ein FPGA braucht keinen Reset, das ist nach dem Laden schon definiert. Z.B. so wie's Neuling_1 gemacht hat:
1 | type zustaende is (s0,s1); |
2 | signal zustand:zustaende:=s0; |
3 | signal folge:zustaende:=s0; |
4 | signal counter:std_logic_vector(2 downto 0):="000"; |
Einen Reset-Eingang braucht nur der Entwickler für seinen Reset-Knopf. Aber wenn schon ein Reset, dann bitte synchron. Was haben wir schon für Dinge mit asynchronen Signalen erlebt... Und ein Reset ist das Asynchronste überhaupt. Dieser globale Reset mit seinem globalen Reset-Netzwerk kann dir z.B. mit einem kleinen Spike das halbe FPGA zurücksetzen, aber die andere Hälfte nicht. Und das gibt lustige Fehler: jedesmal einen anderen. Warum nicht so (wir alle lieben synchrone Designs):
1 | process (RESET,CLK) |
2 | variable count : integer range 0 to 2; |
3 | begin
|
4 | if rising_edge(CLK) then |
5 | if RESET = '1' then |
6 | count := 0; |
7 | zustand <= s0; |
8 | else
|
9 | case zustand is |
10 | when s0 => OUTPUT2 <= conv_std_logic_vector(count,4); |
11 | count := count +1; |
12 | if count > 2 then |
13 | count := 0; |
14 | zustand <= s1; |
15 | else
|
16 | -- mach irgend etwas
|
17 | end if; |
18 | |
19 | when s1 => OUTPUT2 <=conv_std_logic_vector(count,4); |
20 | zustand <=s0; |
21 | end case; |
22 | end if; |
23 | end if; |
24 | end process; |
Vorher aber den Reset-Eingang wie üblich über zwei FFs auf den CLK synchronisieren.
@lkmiller Danke, ich hab ja in nem Beitrag weiter oben schon geschrieben, das ich noch nicht viel Erfahrung mit VHDL habe. Ja den Reset braucht man hier sicher nicht, aber in der Simulation habe ich es schon benötigt um definierte Ausgangszustäbde zu bekommen. Warscheinlich hätte ich das damals dort auch anders machen können aber na ja wie gesagt ich lerne noch! Auch der Tipp mit dem Syncronen Reset und den Folgefehlern die entstehen könne , ist sehr interresannt. Ja als Softwareentwickler muss mann mit dem parallelen Ablauf im FPGA schon umdenken ! Gruß joachim
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.