首页 文章

简单的状态机问题

提问于
浏览
3

我有一个非常简单的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;

非常感谢代码改进这个简单FSM的评论!

3 回答

  • 2

    我会支持马丁 .

    将双向性保持在顶层,然后将下面的所有逻辑看作两条总线,一条输入总线和一条输出总线 .

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

    然后,当输出有效时,双向数据总线被分配输出总线,当无效时,Z被分配给输出总线 .

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

  • 0

    此外,当您确实需要变量赋值 := 时,您使用了几次信号分配符号 <= .

    所以,你想写

    v.f := a;
    

    用于将值 a 赋值给变量 v 的字段,和

    s <= a;
    

    a 分配给信号或端口 s .

  • 1

    使用 inout s最好将其在顶层分成两个信号 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上的许多受人尊敬的海报都是这种观点 .

相关问题