Hallo, ich möchte in VHDL eine Finite-State-Machine programmieren. Ich habe 4 Zustände, die die SM annehmen kann. Allerdings ist mir das Prinzip noch nicht klar, wie man in VHDL gewährleistet, dass die FSM ab Start im Zustand_1(z0) beginnt und nicht irgendwo anders. Danke im Voraus! library IEEE; use IEEE.std_logic_1164.all; ENTITY fsm_tst IS PORT( clk, Sin : IN std_logic; Zustand : BUFFER std_logic_vector(1 downto 0); Sout : OUT std_logic); END fsm_tst; ARCHITECTURE arch_fsm_tst OF fsm_tst IS CONSTANT z0 : std_logic_vector(1 downto 0) := "00"; CONSTANT z1 : std_logic_vector(1 downto 0) := "01"; CONSTANT z2 : std_logic_vector(1 downto 0) := "10"; BEGIN Zustandsfolge : PROCESS( clk ) BEGIN IF( clk'EVENT AND clk = '1' ) then CASE Zustand IS WHEN z0 => IF Sin = '1' THEN Zustand <= z1; ELSE Zustand <= z0; END IF; WHEN z1 => Zustand <= z2; WHEN z2 => Zustand <= z0; WHEN OTHERS => -- Dummy-Zustand Zustand <= z0; END CASE; END IF; END PROCESS; Ausgaenge : PROCESS( Zustand, Sin ) BEGIN CASE Zustand IS WHEN z0 => Sout <= '0'; WHEN z1 => Sout <= '1'; WHEN z2 => Sout <= Sin; WHEN OTHERS => Sout <= '0'; END CASE; END PROCESS; END arch_fsm_tst;
Dazu gibt's mehrere Möglichkeiten. - Du verwendest ein RESET Signal welches den Zustand z0 erzwingt. Dies funktioniert immer und Simulation und HW stimmen garantiert überein. - Du verwendest einen Initialisierungswert. Dazu ist es besser, wenn Dein Zustandsvektor ein internes Signal ist, und nicht ein BUFFER-Signal deiner Entity.
1 | ENTITY fsm_tst IS |
2 | PORT( clk, Sin : IN std_logic; |
3 | Zustand : OUT std_logic_vector(1 downto 0); |
4 | Sout : OUT std_logic); |
5 | END fsm_tst; |
6 | |
7 | ARCHITECTURE arch_fsm_tst OF fsm_tst IS |
8 | CONSTANT z0 : std_logic_vector(1 downto 0) := "00"; |
9 | CONSTANT z1 : std_logic_vector(1 downto 0) := "01"; |
10 | CONSTANT z2 : std_logic_vector(1 downto 0) := "10"; |
11 | |
12 | signal Z : std_logic_vector(1 downto 0) := z0; |
13 | |
14 | BEGIN
|
15 | Zustandsfolge : PROCESS( clk ) |
16 | BEGIN
|
17 | IF rising_edge(clk) then |
18 | CASE Zustand IS |
19 | ...
|
20 | END PROCESS; |
21 | |
22 | Zustand <= Z; |
23 | END
|
Das Problem dabei ist, daß ältere Compiler nicht imstande sind, den Initialisierungswert in HW umzusetzen. Wenn Du aber z.B. Xilinx Webpack/ISE ab Version 7.1 verwendest, dann sollte es klappen.
Eine schöne Methode für die Zustandsdeklaration.
1 | architecture beh1 of fsm is |
2 | type state_type is (s1,s2,s3,s4); |
3 | signal state: state_type; |
4 | begin
|
5 | process1: process (clk, reset) |
6 | begin
|
7 | if (reset =’1’) then |
8 | state <= s1; |
9 | elsif (clk=’1’ and clk’Event) then |
10 | case state is |
11 | when s1 => |
12 | if x1=’1’ then |
13 | state <= s2; |
14 | else ..... |
und nie das when others vergessen.... Sebastian
@Klaus Felser -ARCHITECTURE arch_fsm_tst OF fsm_tst IS -CONSTANT z0 : std_logic_vector(1 downto 0) := "00"; -CONSTANT z1 : std_logic_vector(1 downto 0) := "01"; -CONSTANT z2 : std_logic_vector(1 downto 0) := "10"; -signal Z : std_logic_vector(1 downto 0) := z0; -BEGIN -Zustandsfolge : PROCESS( clk ) 1: Das Signal Z wird in Architekture initialisiert. Bedeutet dies, dass VHDL diesen Teil des Moduls nur 1x durchläuft, und nicht unendlich oft, wie es bei anderen Teilen des Programmes der Fall ist? Als Bsp: Jeder Prozess wird so oft gestartet, so oft der Prozess aufgerufen wird. 2: -Das Problem dabei ist, daß ältere Compiler nicht imstande sind, den -Initialisierungswert in HW umzusetzen. -Wenn Du aber z.B. Xilinx Webpack/ISE ab Version 7.1 verwendest, dann -sollte es klappen. Kann ich mit Quartus 5.1 sicher sein, dass der Initialisierunswert in HW umgesetzt wird?
1) Im Prinzip ja. Z wird mit 1 x mit z0 initialisiert. 2) Weiss ich leider nicht, ich habe mit Altera noch nie gearbeitet. Vielleicht weiss es jemand anderer. Man kann zwar z0 als "00" wählen, wie Du es gemacht hast und sich drauf verlassen, daß alle FF mit '0' aufwachen. Falls aber der Compiler oder Fitter deine Gleichungen optimiert und ein Bit deines Zustandsvektors invertiert, weil es günstiger zum Implementieren ist, dann wacht deine FSM mit dem falschen Startwert auf. Dies ist zwar unwahrscheinlich, könnte aber passieren.
>Kann ich mit Quartus 5.1 sicher sein, dass der Initialisierunswert in >HW umgesetzt wird? Kurz und knapp: Ja
Hallo, die oben gezeigte Zwei-Prozess Dartsellung einer FSM läßt sich auch in eine Ein-Prozess-Darstellung vereinfachen, zudem läßt sich über die Typendeklaration eine FSM (Typ Moore) inklu Zuständen deklarieren. Desweiteren wird das Eingangssignal auf den Systemtakt "clk" eingesampelt (Synchronisierung)
1 | ENTITY FSM_example IS |
2 | PORT ( clk : std_logic; |
3 | reset : std_logic; |
4 | input : std_logic_vector(1 DOWNTO 0); |
5 | output : std_logic_vector(3 DOWNTO 0); |
6 | );
|
7 | END FSM_example; |
8 | |
9 | |
10 | ARCHITECTURE FSM_beh OF FSM_example IS |
11 | |
12 | TYPE FSM_1 IS (State_1, State_2, State_3); |
13 | SIGNAL State_FSM : FSM_1 := State_1; |
14 | .
|
15 | SIGNAL input_q : std_logic; |
16 | .
|
17 | |
18 | One_Procss_Discription : PROCESS(clk,reset) |
19 | IF reset = '1' THEN |
20 | input_q <= '0'; -- Reset-Initialisierung |
21 | output <= (OTHERS => '0'); -- " |
22 | State_FSM <= State_1; -- " , |
23 | Startzustand
|
24 | ELSIF rising_edge(clk) THEN |
25 | input_q <= input; -- Einsampeln des |
26 | Eingangssignal auf Systemtakt "clk" |
27 | CASE FSM_1 IS |
28 | WHEN State_1 => |
29 | IF input_q = '1' THEN -- Startwert der FSM vom Typ Moore |
30 | output <= "1000"; |
31 | State_FSM <= State_2; |
32 | END IF; |
33 | |
34 | WHEN State_2 => |
35 | output <= "0110"; |
36 | State_FSM <= State_3; |
37 | |
38 | WHEN State_3 => |
39 | output <= "1111"; |
40 | State_FSM <= State_1; |
41 | |
42 | WHEN OTHERS => -- alle irregulären Zustände |
43 | output <= "0000"; -- werden mit mit |
44 | Reset-Values |
45 | State_FSM <= State_1; -- initialisiert, d.h. |
46 | "Aufhängen" der FSM wird vermieden |
47 | |
48 | END CASE FSM_1; |
49 | END IF; |
50 | END PROCESS; |
51 | END FSM_beh; |
Habe die FSM mal auf die Schnelle eingehackt....hoffe, es haben sich keine Fehler eingeschlichen. Die Ein-Prozess-Darstellung erreicht die beste Simulationseffizienz und da die Übergangs- und Ausgangsschaltnetze in dem getakteten Prozess integriert sind, werden für alle im Prozess verwendeten Signale D-FF durch das Synthesetool D-FF generiert. Gruß Tom
Noch ein Fehler gefunden.... So ist richtig
1 | ENTITY FSM_example IS |
2 | PORT ( clk : IN std_logic; |
3 | reset : IN std_logic; |
4 | input : IN std_logic_vector(1 DOWNTO 0); |
5 | output : OUT std_logic_vector(3 DOWNTO 0); |
6 | );
|
7 | END FSM_example; |
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.