2011-04-16 228 views
0

我已經看到了按照用於在Verilog中的模塊狀態的變化:用Verilog FSM狀態變化

state <= 2'b10;

state <= #1 IDLE;

爲什麼< =使用的並不僅僅是=?使用#1的目的是什麼?這有什麼不同嗎?

下面是FSM的一些Verilog代碼,顯示了正在使用的第一個Verilog代碼。如果它被替換爲第二個,它的工作原理是否相同?

module fsm(clk, rst, inp, outp); 

    input clk, rst, inp; 
    output outp; 

    reg [1:0] state; 
    reg outp; 

    always @(posedge clk, posedge rst) 
    begin 
    if(rst) 
     state <= 2'b00; 
    else 
    begin 
     case(state) 
     2'b00: 
     begin 
      if(inp) state <= 2'b01; 
      else state <= 2'b10; 
     end 

     2'b01: 
     begin 
      if(inp) state <= 2'b11; 
      else state <= 2'b10; 
     end 

     2'b10: 
     begin 
      if(inp) state <= 2'b01; 
      else state <= 2'b11; 
     end 

     2'b11: 
     begin 
      if(inp) state <= 2'b01; 
      else state <= 2'b10; 
     end 
     endcase 
    end 
end 

回答

7

在順序邏輯always塊像你,最好是使用非阻塞賦值(<=)代替阻塞賦值(=)。仿真將更好地代表實際產生的邏輯。

在純RTL Verilog代碼,如果你正在使用非阻塞賦值所有時序邏輯,應該沒有理由使用#1延遲。

我也看到其他人使用#這樣的延遲。有時候,這是由於在同一模擬中混合了RTL和門網表。其他時間則用於補償不良建模。如果可以的話,你應該避免在RTL代碼中使用延遲。

參見: Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!

而且,最好是使用parameter命名您的每一個狀態。如果一個州的名稱是IDLE而不是2'b10,那麼它就更有意義。

+1

太陽紙凹凸 – 2011-04-16 20:15:46

2

Verilog本質上是非確定性的。這意味着一般來說,模擬有多種可能的結果,這些結果都是不同的,但根據標準是有效的。

要避免來自時鐘始終塊的非確定性行爲,必須使用爲其他塊(非本地變量)中使用的變量使用非阻塞賦值。對於更詳細的分析,請參見我的博客文章的主題:

http://www.sigasi.com/content/verilogs-major-flaw

合成工具通常接受總是主頻塊阻塞非本地變量賦值,但是這確實是一個錯誤,因爲沒有辦法他們可以保證合成的邏輯將表現得像模型一樣(因爲這樣的模型是非確定性的)。

與此相反,你會從許多人聽到的話,這樣的懸崖卡明斯的通俗報紙,有沒有只需要使用非阻塞賦值爲當地變量。對局部變量來說,阻塞賦值是完全可以接受的。這是相關的,因爲它允許在內部建模中使用純粹的「可變」語義(如在編程語言中)。

在純粹的RTL風格建模中,#1延遲只是開銷。