Ich versuche, eine sehr einfache Zustandsmaschine zu schreiben, die ein Kombinationsschloss implementiert.
Der Code lautet: Switch1 -> Switch2 -> Switch3 -> Switch4
Ich erkenne, dass es Schalter 7, 6, 5, 4 entsprechend im Code ist.
Wenn dies nicht in dieser Reihenfolge erfolgt, wird der Fehlerstatus (falsch) angezeigt.
state
Das Problem, das ich habe, ist, dass es sich zwar state_start
(wie ich es auf den LEDs sehe) nicht ändert state_1_right
und stattdessen nur die error_state
. Ich weiß, dass es in diese if-Anweisung geht, weil ich das else
in geändert habe state <= "00001010";
und es zeigt das an.
Was mache ich falsch? Ich sehe keinen Fehler in meiner Logik (es sei denn, es gibt einen seltsamen Schaltersprung).
Hier ist der Code, den ich jetzt versuche:
entity CombinationLockFSM is
Port(
Switches: in std_logic_vector(7 downto 0);
LEDs: out std_logic_vector(7 downto 0)
);
end CombinationLockFSM;
architecture Behavioral of CombinationLockFSM is
constant state_start: std_logic_vector(7 downto 0) := "10000000";
constant state_1_right: std_logic_vector(7 downto 0) := "01000000";
constant state_2_right: std_logic_vector(7 downto 0) := "00100000";
constant state_3_right: std_logic_vector(7 downto 0) := "00010000";
constant state_error: std_logic_vector(7 downto 0) := "00001111";
signal state: std_logic_vector(7 downto 0) := (others => '0');
begin
LEDs <= state;
process(Switches)
begin
case Switches is
when "00000000" =>
state <= state_start;
when "10000000" =>
if state = state_start then
state <= state_1_right;
else
state <= state_error;
end if;
when "11000000" =>
if state = state_1_right then
state <= state_2_right;
else
state <= state_error;
end if;
when "11100000" =>
if state = state_2_right then
state <= state_3_right;
else
state <= state_error;
end if;
when "11110000" =>
if state = state_3_right then
state <= "11110000";
else
state <= state_error;
end if;
when others =>
state <= state_error;
end case;
end process;
end Behavioral;
Vielen Dank an Brian Drummond für das Finden des Fehlers in meiner Logik und den Vorschlag einer Uhr. Ich musste den if-Anweisungen etwas zusätzliche Logik hinzufügen, da die Uhr den case-Block schnell durchläuft und der Zustand gleich bleiben konnte.
Hier ist der aktualisierte Code, der das Problem behebt:
entity CombinationLockFSM is
Port(
mclk: in std_logic;
sw: in std_logic_vector(7 downto 0);
Led: out std_logic_vector(7 downto 0)
);
end CombinationLockFSM;
architecture Behavioral of CombinationLockFSM is
constant state_start: std_logic_vector(7 downto 0) := "10000000";
constant state_1_right: std_logic_vector(7 downto 0) := "01000000";
constant state_2_right: std_logic_vector(7 downto 0) := "00100000";
constant state_3_right: std_logic_vector(7 downto 0) := "00010000";
constant state_4_right: std_logic_vector(7 downto 0) := "11110000";
constant state_error: std_logic_vector(7 downto 0) := "00001111";
signal state: std_logic_vector(7 downto 0) := (others => '0');
begin
Led <= state;
process(mclk)
begin
if rising_edge(mclk) then
case sw is
when "00000000" =>
state <= state_start;
when "10000000" =>
if state = state_start or state = state_1_right then
state <= state_1_right;
else
state <= state_error;
end if;
when "11000000" =>
if state = state_1_right or state = state_2_right then
state <= state_2_right;
else
state <= state_error;
end if;
when "11100000" =>
if state = state_2_right or state = state_3_right then
state <= state_3_right;
else
state <= state_error;
end if;
when "11110000" =>
if state = state_3_right or state = state_4_right then
state <= state_4_right;
else
state <= state_error;
end if;
when others =>
state <= state_error;
end case;
end if;
end process;
end Behavioral;
Die andere Antwort ist richtig, dass eine Uhr benötigt wird.
Ignorieren Sie jedoch das von ihm verlinkte Zwei-Prozess-Beispiel: Suchen Sie an den üblichen Stellen nach "VHDL Single Process State Machine", um eine bessere Lösung zu finden.
http://www.openhdl.com/vhdl/664-vhdl-tip-single-process-vhdl-state-machine-design.html für einen.
Möglicherweise benötigen Sie eine Uhr, um die Statusänderungen zu synchronisieren.
Könnte Switch Bounce sein, aber wenn der erste springt, scheint es, als würde er zu start_state zurückkehren, nicht zu state_error, denke ich. Verwenden Sie physische Schalter?
Ich drucke Beispielcode von hier http://esd.cs.ucr.edu/labs/tutorial/fsm.vhd nach, zum Beispiel für die Synchronisierung mit der Uhr für die Statusänderungen.
-----------------------------------------------------
-- VHDL FSM (Finite State Machine) modeling
-- (ESD book Figure 2.7)
-- by Weijun Zhang, 04/2001
--
-- FSM model consists of two concurrent processes
-- state_reg and comb_logic
-- we use case statement to describe the state
-- transistion. All the inputs and signals are
-- put into the process sensitive list.
-----------------------------------------------------
library ieee ;
use ieee.std_logic_1164.all;
-----------------------------------------------------
entity seq_design is
port( a: in std_logic;
clock: in std_logic;
reset: in std_logic;
x: out std_logic
);
end seq_design;
-----------------------------------------------------
architecture FSM of seq_design is
-- define the states of FSM model
type state_type is (S0, S1, S2, S3);
signal next_state, current_state: state_type;
begin
-- cocurrent process#1: state registers
state_reg: process(clock, reset)
begin
if (reset='1') then
current_state <= S0;
elsif (clock'event and clock='1') then
current_state <= next_state;
end if;
end process;
-- cocurrent process#2: combinational logic
comb_logic: process(current_state, a)
begin
-- use case statement to show the
-- state transistion
case current_state is
when S0 => x <= '0';
if a='0' then
next_state <= S0;
elsif a ='1' then
next_state <= S1;
end if;
when S1 => x <= '0';
if a='0' then
next_state <= S1;
elsif a='1' then
next_state <= S2;
end if;
when S2 => x <= '0';
if a='0' then
next_state <= S2;
elsif a='1' then
next_state <= S3;
end if;
when S3 => x <= '1';
if a='0' then
next_state <= S3;
elsif a='1' then
next_state <= S0;
end if;
when others =>
x <= '0';
next_state <= S0;
end case;
end process;
end FSM;
-----------------------------------------------------
geometrisch
MLM