2010-10-13 92 views
3

我有一個非常簡單的FSM,它應該驅動外部RAM的某些輸出信號。我遇到的問題是處理數據總線 ,它可以輸入以及輸出......我不太確定我如何在我的FSM中最好地處理 這種情況。該問題源於以下行:簡單狀態機問題

v.sram_data <= io_sram_data; 

顯然,左手側是一個變量而右手側是一個信號。如何處理FSM中信號的「好」方式,就像我擁有的​​那樣?

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的評論!

回答

2

使用inout更好地將其在頂層分爲兩個信號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上的許多備受讚譽的海報都是這種觀點。

1

另外,當您確實需要變量賦值:=時,您幾次使用信號賦值符號<=

所以,你想要寫

v.f := a; 

爲可變v的領域分配價值a,並且

s <= a; 

分配a信號或端口s

0

我會在這方面與馬丁一起。

將雙向性留在頂層,然後看下面的所有邏輯,看到兩條總線,一條輸入總線和一條輸出總線。

輸入總線始終與雙向數據總線相同。

然後雙向數據總線在輸出有效時被賦值爲輸出總線,而在無效時賦值爲Z.

Z將被總線的實際輸入狀態覆蓋。