2013-12-10 49 views
0

我們正在實施VHDL以太網MAC控制器..在FSM中處理異步信號的正確實現是什麼?

開始的,這裏是我的代碼的代碼片斷..

-- next state 
PROCESS(p_state, phy_start, phy_ctr, phy_clk) 
BEGIN 
    CASE p_state IS 
     WHEN sIDLE => 
      IF(phy_start = '1' or rising_edge(phy_start)) THEN 
       n_state <= sPRE; 
      ELSIF(phy_start'event AND phy_start='0') THEN 
       n_state <= n_state; 
      ELSE 
       n_state <= sIDLE; 
      END IF; 
    ............ 

的問題是,我的教授告訴我有關phy_start爲在rising_edge()中的時鐘信號必須僅與僅一個phy_clk時鐘相關聯。我想要發生的是當phy_start斷言時,它會在下一個時鐘週期進入sPRE狀態。斷言在時鐘的上升沿完成。我曾嘗試

PROCESS(p_state, phy_start, phy_ctr, phy_clk) 
BEGIN 
    CASE p_state IS 
     WHEN sIDLE => 
      IF(phy_start = '1') THEN 
       n_state <= sPRE; 
      ELSIF(phy_start'event AND phy_start='0') THEN 
       n_state <= n_state; 
      ELSE 
       n_state <= sIDLE; 
    ............. 

,但它不進入phy_start =「1」,因爲它在過渡發生。(還有就是我們所說的建立時間,其中的數據必須是穩定的,持續時間,以便被正確地讀取)。那麼正確的實施是什麼?或者,如果斷言發生在上升沿,或者phy_start必須在時鐘的下降沿斷言,我別無選擇,只能斷言2個時鐘週期的phy_start。此外,下一個狀態邏輯的正確靈敏度列表是什麼?

回答

1

如果一切按照phy_clk計時,您不應該在其他信號上使用rising_edge()或'event。這些與時鐘相關,而不是信號。 如果要檢測時,同步於phy_clk上升的信號,你應該這樣進行:

process(phy_clk,nreset) 
begin 
    if nreset = '0' then 
    phy_start_d <= '0'; 
    elsif phy_clk = '1' and phy_clk'event then 
    phy_start_d <= phy_start; 
    end if; 
end process; 
phy_start_p <= phy_start and not phy_start_d; 

phy_start_p信號被設置爲1,只有當phy_start上升,它與phy_clk完全同步;

+0

什麼是應在NRESET? – Xegara

+0

您通常需要在開始時重置信號,以便從衆所周知的配置開始。通常情況下,復位信號爲低電平有效,復位信號反相。出於這個原因,我把它稱爲nreset(取消重置)。在這裏,您可以簡單地刪除它,但對於其他類型的設計,如果您在開始時沒有重置狀態,則會出現一些嚴重問題。 – Scola

+0

當它在時鐘的上升沿聲明時,phy_start的值會如何,因爲您設計了一個邏輯,就像您提供的一樣? – Xegara

0

目前已與解答相關問題最近,你可以找到在: how many processes i need to monitor two signals?

要記住的是VHDL是用於描述硬件(設計)是有用的,所以 綜合工具可以轉換該描述適合通常觸發器(順序設計)和門(組合 設計)的可用硬件 。綜合工具通常會對編寫VHDL的 提出一些建議,因此硬件轉換將順利進行。

對於觸發器具有異步復位(RST)和上升沿時鐘(CLK),與由可選的柵極產生 下一個值,所述VHDL通常爲:

-- Template for flip flops 
process (clk, rst) is 
begin 
    if rising_edge(clk) then 
    -- Flip flops outputs updated on rising edge of clk 
    end if; 
    if rst = '1' then 
    -- Flip flops outputs assigned with constant value when rst is '1' 
    end if; 
end process; 

只有rstclk應該在靈敏度列表,因此在過程中的表達式中使用的其他信號 不應包括在內。用於 的任何表達式都會生成觸發器的值,並由該工具轉換爲邏輯門。

只有上升沿時鐘應該用於觸發器,除非有良好的 理由使用下降沿時鐘,或者甚至是兩個邊沿,因爲只使用單個邊沿將使定時約束變得更容易。

如果未使用異步復位,則從 靈敏度列表中刪除rst,並刪除相關的if語句。

對於純柵極的VHDL通常,假設使用VHDL-2008:

-- Template for gates 
process (all) is 
begin 
    -- Gates outputs updated based 
end process; 

簡單表達或只下降的過程和寫入:

my_signal <= my_expression; 

所以回到所述特定代碼,那麼有可能將其作爲單個 過程以phy_clk作爲時鐘:

PROCESS (phy_clk) 
BEGIN 
    IF RISING_EDGE(phy_clk) THEN 
     CASE p_state IS 
      WHEN sIDLE => 
       p_state <= ... -- New value for state based on signals 

當需要對信號變化作出反應時,如phy_start從 '0'變爲'1',則可以製作具有單週期延遲版本的信號,例如,以及表達式可以在代碼等書面 :

if (phy_start_ff = '0') and (phy_start = '1') then -- phy_start from 0 to 1 
    .. 
+0

在phy_start的上升沿,phy_start是否會被檢測爲'1'? – Xegara

+0

該描述假設所有狀態改變都與一個時鐘同步,假定它是'phy_clk'。所以狀態直到'phy_clk'的上升沿才被更新,但如果'phy_start'然後是'1'並且在前一個'phy_clk'上升沿是'0',則檢測到該變化。我用'p_state'(當前狀態)更新的信息更新了上面的'PROCESS(phy_clk)'。 –

+0

如果phy_start與phy_clk同時聲明會怎麼樣?在這種情況下,phy_start尚未達到所需的最小時間設置,並且信號phy_start已經在if條件中讀取了。它是否會讀取不確定的值? – Xegara

0

如果phy_start另一個進程創建同步,那麼你有沒有問題。

剛讀它在你的其他同步的過程中,和比較反對您從最後一個時鐘週期中存儲的值,當信號從01變化來檢測:

process (phy_clk) 
    variable last_start : std_logic := '0'; 
begin 
    if rising_edge(phy_clk) then 
    if phy_start = '1' and last_start = '0' then 
     -- do something in here 
    end if; 
    last_start := phy_start; 
    end if; 
end process; 
相關問題