2012-09-29 40 views
1

我想鎖定一個信號,但是當我嘗試這樣做時,我得到一個週期的延遲,我該如何避免這種情況?無延遲鎖存信號

myLatch: process(wclk, we) -- Can I ommit the we in the sensitivity list? 
begin 
    if wclk'event and wclk = '1' then 
     lwe <= we; 
    end if; 
end process; 

但是,如果我嘗試這一點,看看海浪模擬LWE期間由WCLK的一個週期延遲。我想要達到的目標是在wclk的上升沿對we進行採樣,並保持穩定直到下一個上升沿。然後,我將鎖定信號分配給架構中定義的另一個實體端口映射。

==============================================

嗯,我發現我必須省略wclk'event才能獲得鎖存器而不是觸發器。這對我來說似乎相當不直觀。通過簡單地縮短我採樣鎖存信號的時間,我從鎖存器變成觸發器。任何人都可以解釋爲什麼這是和我的看法是錯誤的。 (我是VHDL的初學者)

回答

2

首先,你在上面粘貼過程中的幾點看法:

myLatch: process(wclk, we) 
begin 
    if wclk'event and wclk = '1' then 
    lwe <= we; 
    end if; 
end process; 
  1. 信號我們可以從敏感列表被省略,因爲你所描述一個鐘錶過程。如果您選擇使用一個進程(同步重置不需要添加到靈敏度列表中),那麼此類進程的靈敏度列表中所需的唯一信號是時鐘和異步復位。

  2. 而不是使用if wclk'event and wclk = '1' then你應該使用if rising_edge(wclk) thenif falling_edge(wclk) then的,有一個在原因here一個很好的博客文章。

通過省略wclk'event從時鐘控制處理改變的過程中,以一個組合過程中,像這樣:

myLatch: process(wclk, we) 
begin 
    if wclk = '1' then 
    lwe <= we; 
    end if; 
end process; 

在一個組合過程中的所有輸入應存在於靈敏度列表,以便在列表中有wclkwe是正確的,因爲它們對輸出有影響。通常情況下,您應確保lwe在您的if語句的所有情況下都被分配以避免推斷閂鎖,但這似乎是您在這種情況下的打算。

鎖存器一般應該避免,所以如果你發現自己需要一個,你應該停下來考慮一下你的方法。 Doulos有幾篇有關閂鎖herehere的文章,您可能會覺得有用。

您聲明所有您想要實現的是在wclk的上升沿對we進行採樣,並保持穩定直到下一個上升沿。下面的過程將做到這一點:

store : process(wclk) 
    begin 
    if rising_edge(wclk) then 
     lwe <= we; 
    end if; 
    end process; 

有了這個過程中,lwe將與we後的wclk每個上升沿的值進行更新,並保持有效的一個時鐘週期。

讓我知道,如果這清除了你的東西。

+0

這對我來說非常有價值,我將不得不調查爲什麼要避免閂鎖部分。但如果不確定的話,我不得不提出一個新的問題。由於我只是爲一個寄存器文件寫一個子模塊,並且不能改變外部模塊的時序,所以我看不到任何方式的鎖定(Studentassignment,實現一個帶有單端口RAM的寄存器文件) – ted

2

不管你信不信,這個問題實際上是在您的測試平臺。這與VHDL仿真模型的工作方式有關。

VHDL通常用於同步的硬件設計 - 這意味着,使用觸發器的上升沿該樣本和下降沿設定輸出,使得有讀寫之間沒有競爭條件。但是在VHDL中,這種主/從邏輯實際上並未使用相反的時鐘邊沿進行仿真。

考慮一個過程

process (clock) begin 
    if rising_edge(clock) then 
     a <= b; 
    end if; 
end process; 

在模擬時間步長的開始,如果clock剛剛升起,if將執行。然後分配a <= b將被執行,這不會立即導致分配的發生,但時間表分配的時間步長結束。

所有進程都運行完畢後,然後所有預定的任務發生。這意味着在下一個時間步驟之前,任何進程都不會「看到」a的新值。

Time    a   b   Actions 
Start of ts 1 '0'   '1'  a <= '1' is scheduled 
End of ts 1  '1'   '0'  a <= '1' is executed 
Start of ts 2 '1'   '0'  a <= '0' is scheduled 
End of ts 2  '0'   '1'  a <= '0' is executed 

所以,當你在波形查看,你會看到什麼是a顯然被設置在時鐘的上升沿,並按照b一個時鐘週期延遲;您沒有看到導致這種情況發生的分配的中間調度。

當然,在現實生活中,沒有「時間步的結束」,並且當觸發器的從屬部分觸發時,即在負邊緣上,信號a的實際改變發生。 (也許對於VHDL來說,使用負面邊緣會更容易混淆;但是,噢,這就是它的工作原理)。

以下是爲您的鎖代碼的兩個測試平臺:

在第一個,如果你在波形查看器看一下,你會清楚地看到你的描述 - lwe似乎被延遲了1個時鐘週期 - 但實際上,延遲發生在設置爲counter的非阻塞賦值 - 所以當發生上升沿時,we實際上並沒有新的價值。第二,你看不到這樣的延遲; lwe正好在上升沿設置爲當時的值we

對於Verilog的相關主題,請參閱Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill

1

你有這個過程是你根據你的描述想要的東西,但「我們」應該從靈敏度列表中刪除。如果這不起作用,你認爲它應該是你的測試臺/仿真幾乎肯定是一個問題。 (請參閱Owen的答案)具體而言,您可能很晚才更改「我們」的價值,以便觸發器鎖定之前的值而不是新的值。

我很想知道這個信號的來源是什麼,如果它是一個異步信號,可以隨時改變,你將不得不添加一些邏輯來防止亞穩態。

要回答關於鎖存器的第二個問題,省略wclk'event將導致鎖存器是正確的。然而,這個過程不會做你想做的事情,因爲它會在整個時鐘的正半週期間將'我們'的變化傳播到'lwe'。你的問題的簡短答案是實現這種行爲需要一個鎖存器,而原始過程描述的行爲需要一個觸發器。