2013-03-26 35 views
1

處於始終塊想知道有關事件控制語句的行爲:事件控制@(posedge時鐘)

always @(posedge clk) begin: TEST 
    ... 
    @(wait_for_signal_from_subsystem); 
    ... 
    @(wait_for_another_signal_from_subsystem); 
    ... 
end 

會的過程被「卡住」,直到事件信號進來,還是會重新開始每當一個時鐘邊緣進來?

也是這種可綜合的(Quartus II說yes,但還沒有模擬...)?這是一個很好的做法還是有其他更好的方法來解決這個問題?

回答

1

是的,它會「卡住」,就像你會說的那樣。一次只能激活塊的一個「循環」,如果沒有完成循環,則不會重新輸入。

由於塊內的等待操作,您嘗試在此處執行的操作可能無法合成。

我不知道你的設計的確切細節,但我會用一個小的有限狀態機來處理這個問題。我認爲從您的子系統的信號並不比時鐘快,所以它看起來是這樣的:

always @* begin 
    if(state_f == `WAIT_FOR_FIRST) 
     state_nxt = got_first_signal ? `WAIT_FOR_SECOND : `WAIT_FOR_FIRST; 
    else if(state_f == `WAIT_FOR_SECOND) 
     state_nxt = got_second_signal ? `DONE_STATE : `WAIT_FOR_SECOND; 
    else if(state_f == `DONE_STATE) 
     state_nxt = `WAIT_FOR_FIRST; 
    else 
     state_nxt = 2'bxx; 
end 

always @(posedge clk) begin 
    state_f <= state_nxt; 
end 
+0

fsm是一個好主意......只是想在Verilog/HDL中複製「C /高級」風格的功能......但我想你不能擁有一切:( – nehz 2013-03-26 04:03:27

1

假設你正在設計的硬件,而不是非合成測試平臺的代碼,這不是一個很好的做法,有可能贏得無論如何你都不會做你想做的事。

從語言的角度來看,這將編譯和模擬。它塊等待在always塊內的事件,而不是在每個posedge時鐘上重新啓動。我找不到這方面的規範參考,但這是我在模擬中觀察到的。我很好奇,如果你把它合成而沒有錯誤,它會合成什麼。


如果從其他子系統的信號已經是在同一個時鐘域(同步到clk),那麼你可以檢查每個時鐘沿它的狀態,並使用該做些什麼。

always @(posedge clk) begin: TEST 
    if (the_other_signal == 1'b1) begin 
    ... 
    end 
end 

一些其他的事情要考慮:

  • 也許你只在乎當信號斷言/取消斷言。在這種情況下,你需要做一個邊緣檢測。
  • 如果信號與clk不同步,那麼您有一個時鐘域交叉,並且在查看它之前需要同步輸入信號。
+0

謝謝:) ..什麼你的意思是時鐘域交叉btw? – nehz 2013-03-26 05:30:23

+1

時鐘域交叉不是可以在評論框中解釋的主題。 :)下面是一個簡短的介紹:http://eetimes.com/design/eda-design/4018520/Understanding-Clock-Domain-Crossing-Issues – dwikle 2013-03-26 14:05:05

+0

真棒thx .... – nehz 2013-03-27 00:42:23