Simple machine problem

I have a very simple FSM that needs to control some output from external RAM. The problem that I encountered is related to the processing of the data bus that can be input, as well as the output ... I'm not too sure how I can handle the best in this case in my FSM. The problem arises from the following line:

  v.sram_data   <= io_sram_data;

Obviously, the left side is a variable, and the right side is a signal. Is there a “good” way to handle inout signals in FSM like 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;

Thanks so much for the comments that the code improves this simple FSM!

+3
source share
3 answers

inout data_from_outside data_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

, <= , :=.

,

v.f := a;

a v

s <= a;

a s.

+1

.

Leave the bi-directionality at the top level, and then all the logic below that will see the two buses, the input bus and the output bus.

The input bus always matches the bidirectional data bus.

The bi-directional data bus then receives an assignable output bus when the output signal is valid, and Z when it is invalid.

Z will be overridden by the actual bus input state.

0
source

Source: https://habr.com/ru/post/1769359/


All Articles