FSM 进入不可能状态
FSM enters impossible state
我有一个由 3 个状态组成的 FSM:STATIC
、UP
和 DOWN
。
FSM 在STATIC
状态下启动,如果我按向上箭头键,它将移动到UP
状态,然后返回到STATIC
状态。 DOWN
.
同样的事情
一开始 FSM 运行良好,但在随机按下一些键后,它会突然进入一个未指定的状态。 FSM由两个进程组成:
type ALL_STATES is (STATIC, UP, DOWN);
signal STATE, NEXT_STATE: ALL_STATES;
signal posBarraYTOP, posBarraYBOT: std_logic_vector(11 downto 0);
signal movTeclado: std_logic_vector(1 downto 0);
-- ...
Keybd: keyboard port map (input, movTeclado); -- keyboard output
-- ...
bar_FSM_sincrono: process(CLK, RST) -- CLK is the FPGA's clock
begin
if RST='1' then
STATE <= STATIC;
elsif (CLK'event and CLK = '1') then
STATE <= NEXT_STATE; -- in each CLK cycle we move to the next state.
end if;
end process bar_FSM_sincrono;
bar_FSM_cambioest: process(STATE)
begin
case STATE is
when STATIC=>
seg <= "1001001";
if (movTeclado = "01" and posBarraYTOP > 20) then
NEXT_STATE <= UP;
elsif (movTeclado = "10" and posBarraYBOT < 980) then
NEXT_STATE <= DOWN;
else
NEXT_STATE <= STATIC;
end if;
when UP | DOWN =>
NEXT_STATE <= STATIC;
seg <= "1111110";
when others =>
NEXT_STATE <= STATIC;
seg <= "0110111";
end case;
end process bar_FSM_cambioest;
movTeclado
是一个 2 位信号,当用户按下向上 01
或向下 10
键时显示。如果没有按下任何键,则为 00
。 movTeclado 没有给我任何问题。
posBarraYTOP
和posBarraYBOT
是描述边界的两个信号,总是满足这些条件。
我用seg
作为7段显示器的信号来调试,看看FSM处于什么状态。一开始它总是显示 STATIC seg
,因为 UP seg
和 DOWN seg
只显示一个周期。但是当错误发生时,它开始显示 others seg
以及 STATIC seg
。这是STATIC
和others
之间的来回,我不明白,因为什么时候STATE = STATIC
,它应该只过渡到UP
或DOWN
.
感谢您阅读到这里,有谁知道发生了什么事吗?
正如其他评论所建议的那样,您永远不应从多个 process
块驱动信号。我个人不喜欢这样写状态机,有 2 个进程块,因为我觉得它很混乱。
但无论如何,您的第二个流程块(组合流程块)应该只分配 NEXT_STATE
,它永远不应该对 STATE
进行分配,因为第一个流程块已经解决了。
一个问题是您的 bar_FSM_cambioest 敏感度列表不完整。它需要包括所有更改会影响进程输出的信号。
bar_FSM_cambioest: process(STATE, movTeclado, posBarraYTOP, posBarraYBOT)
我的下一个问题是你的时钟有多快?您是否正在尝试从 STATIC 段显示切换到 UP/DOWN 并且返回的速度快于 7 段显示可以可靠更新的速度?
我有一个由 3 个状态组成的 FSM:STATIC
、UP
和 DOWN
。
FSM 在STATIC
状态下启动,如果我按向上箭头键,它将移动到UP
状态,然后返回到STATIC
状态。 DOWN
.
一开始 FSM 运行良好,但在随机按下一些键后,它会突然进入一个未指定的状态。 FSM由两个进程组成:
type ALL_STATES is (STATIC, UP, DOWN);
signal STATE, NEXT_STATE: ALL_STATES;
signal posBarraYTOP, posBarraYBOT: std_logic_vector(11 downto 0);
signal movTeclado: std_logic_vector(1 downto 0);
-- ...
Keybd: keyboard port map (input, movTeclado); -- keyboard output
-- ...
bar_FSM_sincrono: process(CLK, RST) -- CLK is the FPGA's clock
begin
if RST='1' then
STATE <= STATIC;
elsif (CLK'event and CLK = '1') then
STATE <= NEXT_STATE; -- in each CLK cycle we move to the next state.
end if;
end process bar_FSM_sincrono;
bar_FSM_cambioest: process(STATE)
begin
case STATE is
when STATIC=>
seg <= "1001001";
if (movTeclado = "01" and posBarraYTOP > 20) then
NEXT_STATE <= UP;
elsif (movTeclado = "10" and posBarraYBOT < 980) then
NEXT_STATE <= DOWN;
else
NEXT_STATE <= STATIC;
end if;
when UP | DOWN =>
NEXT_STATE <= STATIC;
seg <= "1111110";
when others =>
NEXT_STATE <= STATIC;
seg <= "0110111";
end case;
end process bar_FSM_cambioest;
movTeclado
是一个 2 位信号,当用户按下向上 01
或向下 10
键时显示。如果没有按下任何键,则为 00
。 movTeclado 没有给我任何问题。
posBarraYTOP
和posBarraYBOT
是描述边界的两个信号,总是满足这些条件。
我用seg
作为7段显示器的信号来调试,看看FSM处于什么状态。一开始它总是显示 STATIC seg
,因为 UP seg
和 DOWN seg
只显示一个周期。但是当错误发生时,它开始显示 others seg
以及 STATIC seg
。这是STATIC
和others
之间的来回,我不明白,因为什么时候STATE = STATIC
,它应该只过渡到UP
或DOWN
.
感谢您阅读到这里,有谁知道发生了什么事吗?
正如其他评论所建议的那样,您永远不应从多个 process
块驱动信号。我个人不喜欢这样写状态机,有 2 个进程块,因为我觉得它很混乱。
但无论如何,您的第二个流程块(组合流程块)应该只分配 NEXT_STATE
,它永远不应该对 STATE
进行分配,因为第一个流程块已经解决了。
一个问题是您的 bar_FSM_cambioest 敏感度列表不完整。它需要包括所有更改会影响进程输出的信号。
bar_FSM_cambioest: process(STATE, movTeclado, posBarraYTOP, posBarraYBOT)
我的下一个问题是你的时钟有多快?您是否正在尝试从 STATIC 段显示切换到 UP/DOWN 并且返回的速度快于 7 段显示可以可靠更新的速度?