简单状态机问题 [英] Simple State Machine Problem

查看:93
本文介绍了简单状态机问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a very simple FSM which should drive some output signals of an external RAM. The problem that I have comes with handling the data bus which can be input as well as output... I am not too sure how I can handle best this case in my FSM. The problem comes from the following line:

  v.sram_data   <= io_sram_data;

很显然,左手边是一个变量,而右手边是一个信号.有没有一种不错的"方式来像我一样处理FSM中的inout信号?

Obviously, the left hand side is a variable while the right hand side is a signal. Is there a "nice" way how to handle inout signals in a FSM as the one I have?

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!

Many thanks for comments that code improve this simple FSM!

推荐答案

使用inout更好地将其在顶层分成两个信号data_from_outsidedata_to_outside.然后,您的下层需要实体上的三个元素,一个输入向量,一个输出向量和一个信号来说明何时驱动外部数据.双向信号也无法与记录配合使用.

With inouts its better to split it up right at the top level into two signals data_from_outside and data_to_outside. Then your lower level needs three elements on the entity, one input vector, one output vector and a signal to say when to drive the outside data. Bidirectional signals don't sit well with records either.

然后,顶层需要执行以下操作:

The top level then needs to do:

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上的许多受人尊敬的发布者都对此持反对意见.

From the point of view of style: put everything in one process. There's some debate about this, but many respected posters on comp.arch.fpga and comp.lang.vhdl are of this opinion.

这篇关于简单状态机问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆