2015-04-06 26 views
-2

我想對狀態機進行VHDL編程。在這個狀態機中,一個狀態本身就是另一個狀態機。我怎樣才能從主狀態機調用這個狀態機?什麼其實我想要做的 示例如下:如何從另一個狀態機調用一個狀態機並以VHDL得到響應

主要的狀態機(sm_main.vhd): -

clk_process : process (clk, reset) 
begin 
if(reset = '1') then 
state_reg <= start; 
elsif (clk'event and clk =' 1' ) then 
state_reg <= state_next; 
end if; 
end process; 

state_process : process (state_reg,input,enable) 
begin 
case state_reg is 
when start => 
    if (input =1) then 
     state_next <= wait;  
     else 
     state_next <= start; 
    end if; 

when wait => 
    if (enable =1) then 
    output <= '1'; 
    state_next <= execute; 
     else 
output <='0'; 
    state_next <= wait; 
    end if ; 


when execute => 
    if (enable =1) then 
    state_next <= done; 
    else 

    state_next <= start; 

end if; 

when done => 
if(result = 1) then 
state_next <= execute; 
else 
state_next <= start; 
    end if; 

end case; 
end process; 

子狀態機(sm_execute.vhd): -

的執行上述狀態機的狀態本身就是另一個狀態機程序。

state_process : process (state_reg,a,b)  
begin  
case state_reg is  
when start =>  
    if (a=1) then  
     state_next <= s1;   
     else  
     state_next <= s2;  
    end if;  

when s1 =>  
    if (b =1) then 
    state_next <= s3; 
     else 
    state_next <= s3; 
    end if ; 


when s3=> 
if(c=1) then 
result <= '1'; 
state_next <= s3 
else 
result <='0'; 
state_next <= start 
end case; 
end process; 

我想要的是在sm_main.vhd的執行狀態下調用此sm_execute.vhd。作爲結果的sm_execute的輸出將被用作確定在sm_main.vhd中執行後的下一個狀態的輸入。這意味着我想調用子狀態機程序,並且一旦子狀態機程序完成它的執行,該值也會返回到主狀態機程序。

在此先感謝 Sruthi拉詹

+0

請張貼您當前的代碼顯示有問題的問題。 – 2015-04-06 05:31:15

回答

1

握手。第一臺機器發信號通知第二臺機器啓動,並等待它確認。然後收回啓動信號並等待第二個完成。

這不是唯一的方法,但是你可以把第二個狀態機分成它自己的進程,它可能是最簡單的。

首先SM(主):

SM_1 : process(clock,reset) 
begin 
    if reset = '1' then 
     State_1 <= Idle; 
    elsif rising_edge(clock) then 
     -- default actions 
     Start <= '0'; 
     -- state machine proper 
     case State_1 is 
     ... 
     when Need_Result => 
     Start <= '1'; 
     -- wait here until slave SM starts processing 
     if Done = '0' then 
      State_1 <= Wait_Result; 
     end if; 
     when Wait_Result => 
     if Done = '1' then 
      State_1 <= Have_Result; 
     end if; 
     ... 
     when others => State_1 <= Idle; 
     end case; 
    end if; 
end process; 

第二SM(從):

SM_2 : process(clock,reset) 
begin 
    if reset = '1' then 
     State_2 <= Idle; 
    elsif rising_edge(clock) then 
     case State_2 is 
     when Idle => 
     Done <= '1'; 
     if Start = '1' then 
      Done <= '0'; 
      State_2 <= Start_Process; 
     end if; 
     when Start_Process => 
     State_2 <= Process_Done; 
     when Process_Done => 
     Done <= '1'; 
     if Start = '0' then 
      State_2 <= Idle; 
     end if; 
     when others => State_2 <= Idle; 
     end case; 
    end if; 
end process; 

注意在這個實現中,主等待從開始處理(done = '0';)。這包括從站可能無法立即響應的情況。它不包括Done='0'已經存在的情況,因爲從站正在處理另一個主站的數據。

此外,從站在返回到空閒狀態之前等待主站收回啓動。通常開始將已經是'0',但如果它不是,你可能不希望奴隸立即重新觸發。

如果您可以保證這兩種情況都不會發生,您可以稍微簡化握手,但設計對信號時序的變化更爲敏感。

還請注意Start默認爲'0',因爲默認分配,但Done沒有默認分配,因此它在處理期間保持其狀態。除非您在完成設置爲指示處理已停止時返回到空閒狀態(可能通過錯誤路徑)。

如果處理完成是不確定的,你可能希望主人超時,而不是死鎖等待不會發生的事情。我通過添加一個延時計時器來達到這個目的,這個延時計時器可以用於不同的狀態,用於不同的目的:在這裏它檢測一個凍結的從站並讓我們處理錯誤

首先SM(主):

SM_1 : process(clock,reset) 
    variable Delay : natural range 0 to 100; 
    constant Timeout : natural := 50; 
begin 
    if reset = '1' then 
     State_1 <= Idle; 
     Delay := 0; 
    elsif rising_edge(clock) then 
     -- default actions 
     Start <= '0'; 
     if Delay > 0 then 
     Delay := Delay - 1; 
     end if; 
     -- state machine proper 
     case State_1 is 
     ... 
     when Need_Result => 
     Start <= '1'; 
     -- wait here until slave SM starts processing 
     if Done = '0' then 
      Delay := Timeout; 
      State_1 <= Wait_Result; 
     end if; 
     when Wait_Result => 
     if Done = '1' then 
      State_1 <= Have_Result; 
     elsif Delay = 0 then 
      State_1 <= Timed_Out; -- do error processing 
     end if; 
     ... 
     when others => State_1 <= Idle; 
     end case; 
    end if; 
end process; 
相關問題