3

外部 RAM のいくつかの出力信号を駆動する非常に単純な FSM があります。私が抱えている問題は、出力だけでなく入力も可能なデータ バスの処理に伴うものです...私の 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 を改善するというコメントに感謝します!

4

3 に答える 3

2

s の場合は、最上位レベルで 2 つの信号とinoutに分割することをお勧めします。次に、下位レベルでは、エンティティに 3 つの要素、1 つの入力ベクトル、1 つの出力ベクトル、および外部データを駆動するタイミングを示す信号が必要です。双方向信号は、レコードにも適していません。data_from_outsidedata_to_outside

次に、最上位レベルで次のことを行う必要があります。

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

スタイルの観点からは、すべてを 1 つのプロセスにまとめます。これについてはいくつかの議論がありますが、comp.arch.fpga と comp.lang.vhdl の多くの尊敬される投稿者はこの意見です。

于 2010-10-13T16:37:35.143 に答える
1

<=また、変数割り当てが本当に必要なときに、シグナル割り当てシンボルを数回使用しました:=

だから、あなたは書きたい

v.f := a;

avariable のフィールドに値を代入するためv、および

s <= a;

asignal または portに割り当てますs

于 2010-10-13T19:05:08.930 に答える
0

私はこれについてマーティンの側に立ちます。

双方向性をトップ レベルのままにしておき、その下のすべてのロジックから 2 つのバス (入力バスと出力バス) が見えます。

入力バスは常に双方向データ バスと同じです。

The bi-directional data bus then gets assigned the output bus when output is valid, and Z when it is not valid.

The Z will be overridden by the actual input state of the bus.

于 2010-10-14T09:58:04.613 に答える