2

我的问题是关于合成状态机中使用的第一个状态。

我正在使用 Lattice iCE40 FPGA、用于仿真的 EDA Playground 和用于合成的 Lattice 的 Diamond Programmer。

在下面的示例中,我生成了一系列信号(该示例仅显示了引用状态机的行)。这在模拟中效果很好;即访问的第一个案例是sm_init_lattice并产生所需的信号)。但是,合成版本会直接进入sm_end并停留在那里。结果,输出信号保持低电平。

-- state machine
type t_SM_peaks is (sm_init_lattice,
                    sm_high_start_up, sm_low_start_up, sm_peaks, sm_end);

signal r_SM_peaks : t_SM_peaks;

p_ARRAY_INTS_STDLOG_2D : process (i_Clk) is
begin
  if rising_edge(i_Clk) then
    case r_SM_peaks is
      when sm_init_lattice =>
        ...
        r_SM_peaks <= sm_high_start_up;
      when sm_high_start_up =>
        ...
        r_SM_peaks <= sm_low_start_up;  
      when sm_low_start_up =>
        ...
        r_SM_peaks <= sm_peaks;
      when sm_peaks =>
        ...
        r_SM_peaks <= sm_end;                        -- peaks completed
      when sm_end =>
        ...
        r_SM_peaks <= sm_end;
      when others =>
        r_SM_peaks <= sm_high_start_up;
    end case;
  end if;

end process p_ARRAY_INTS_STDLOG_2D;

但是,如果我进行如下更改(用“更改”表示),那么我会得到我需要的一组信号。

type t_SM_peaks is (sm_init_lattice,
                    sm_high_start_up, sm_low_start_up, sm_end, sm_peaks);

signal r_SM_peaks : t_SM_peaks;

p_ARRAY_INTS_STDLOG_2D : process (i_Clk) is
begin
  if rising_edge(i_Clk) then 
    case r_SM_peaks is
      when sm_init_lattice =>
        ...
        r_SM_peaks <= sm_high_start_up;
      when sm_high_start_up =>
        ...
        r_SM_peaks <= sm_low_start_up;
      when sm_low_start_up =>
        ...
        r_SM_peaks <= sm_peaks;
      when sm_peaks =>
        ...
        r_SM_peaks <= sm_end;                        -- peaks completed
      when sm_end =>
        ...
        -- CHANGE - swapped 'sm_end' for 'sm_init_lattice'
        --r_SM_peaks <= sm_end;
        r_SM_peaks <= sm_init_lattice;             
      when others =>
        r_SM_peaks <= sm_high_start_up;             
    end case;
  end if;

end process p_ARRAY_INTS_STDLOG_2D;

任何人都可以解释发生了什么吗?难道我做错了什么?我会很感激任何建议。

4

1 回答 1

2

在仿真中,VHDL 中的所有内容都默认为其左侧值。在您的代码中,它将是sm_init_lattice,这解释了您的模拟通过的原因。

但是,我没有看到复位信号。因此,在您的硬件中,存储 FSM 状态的触发器将重置为某些状态,但这可能不是代表sm_init_lattice状态的组合。

如果没有您的更改,在硬件中,FSM 可能正在初始化到附近的某个状态sm_end,并且当它进入该状态时,它将保持在那里。通过进行更改,您允许 FSM 在赛道上绕更多圈,因此无论最初发现自己的状态如何,它都会在所有状态中前进。

解决方案是实施适当的复位(异步或同步 - FPGA 人似乎更喜欢同步)。

使用枚举类型对状态机进行编码很好,因为代码易于阅读和维护,您不必提交任何状态编码,并且可以在波形显示上查看您所处的状态。但是,使用枚举类型对状态机进行编码不能让您对未初始化的状态进行建模,这可能是您的问题的原因。System-Verilog 在这方面优于 VHDL,因为它可以声明一个也可以是未知的枚举类型。

于 2018-05-21T14:37:55.357 回答