【问题标题】:Simple State Machine Problem简单状态机问题
【发布时间】:2011-04-24 21:39:03
【问题描述】:

我有一个非常简单的 FSM,它应该驱动外部 RAM 的一些输出信号。我遇到的问题是处理数据总线 既可以输入也可以输出...我不太确定如何处理 在我的 FSM 中最好的这种情况。问题来自以下行:

  v.sram_data   <= io_sram_data;

显然,左侧是变量,而右侧是信号。有没有一种“好”的方式来处理我所拥有的 FSM 中的 inout 信号?

entity sram_fsm is
  port (
     clk              : in std_logic;
     reset            : in std_logic;
     out_sram_rd      : out std_logic;
     out_sram_wr      : out std_logic;
     out_sram_addr    : out std_logic_vector(3 downto 0);
     io_sram_data     : inout std_logic_vector(7 downto 0)

);  
end;

architecture Behavioral of sram_fsm is

  type state_type is (wr_init, wr_data, rd_init, rd_data);

  type reg_type is record
     state       : state_type;
     sram_data   : std_logic_vector(7 downto 0);
     sram_addr   : std_logic_vector(3 downto 0);   
     sram_rd     : std_logic;  
     sram_wr     : std_logic;     
  end record;   

  signal r, rin : reg_type;

  begin

  comb : process (r)
     variable v : reg_type;
begin
v := r;

case r.state is
  when wr_init =>
        v.sram_data    := "00000000";
        v.sram_addr    := "0000";   
  v.sram_rd      := '0';  
  v.sram_wr      := '0';     
  v.state        := wr_data;
  when wr_data =>
  io_sram_data  <= "00001000";
       v.sram_wr     := '1'; 
  v.state       := rd_init;
  when rd_init =>
  v.sram_addr   := "0000";   
  v.sram_rd     := '1';  
  v.sram_wr     := '0';     
  v.state       := wr_data;
  when rd_data =>
  v.sram_data   <= io_sram_data;
        v.state       := wr_init;     
 end case;

     out_sram_addr  <= v.sram_addr;
     out_sram_rd    <= v.sram_rd;    
     out_sram_wr    <= v.sram_wr;    

   rin <= v;

     end process;

regs : process (reset, clk)
begin
  if reset = '0' then
         r.state <= wr_init; 
     elsif rising_edge(clk) then
        r <= rin;
     end if;   
end process;   

 end Behavioral;

非常感谢 cmets 的代码改进了这个简单的 FSM!

【问题讨论】:

    标签: vhdl fpga state-machine


    【解决方案1】:

    使用inouts 最好在顶层将其拆分为两个信号data_from_outsidedata_to_outside。然后你的下层需要实体上的三个元素,一个输入向量,一个输出向量和一个信号来说明何时驱动外部数据。双向信号也不适合记录。

    那么顶层需要做的事情:

    data_pins <= data_to_outside when data_to_outside_enable = '1' else (others => 'Z');
    data_from_outside <= data_pins;
    

    从风格的角度来看:把一切都放在一个过程中。对此存在一些争论,但 comp.arch.fpga 和 comp.lang.vhdl 上的许多受人尊敬的海报都持有这种观点。

    【讨论】:

      【解决方案2】:

      此外,当您确实需要变量赋值 := 时,您曾多次使用信号赋值符号 &lt;=

      所以,你想写

      v.f := a;
      

      用于将值a 分配给变量v 的字段,并且

      s <= a;
      

      a 分配给信号或端口s

      【讨论】:

        【解决方案3】:

        在这点上我会站在马丁一边。

        将双向性留在顶层,然后下面的所有逻辑都看到两条总线,一条输入总线和一条输出总线。

        输入总线始终与双向数据总线相同。

        然后双向数据总线在输出有效时被分配到输出总线,在输出无效时被分配到 Z。

        Z 将被总线的实际输入状态覆盖。

        【讨论】:

          猜你喜欢
          • 2013-06-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-30
          • 2011-08-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多