2016-02-26 561 views

回答

4

我想你問的是下面的區別:

module my_dff (output reg q, input clk, d); //None Blocking style 
    always @(posedge clk) begin 
    q <= d; 
    end 
endmodule 

VS

module my_dff (output q, input clk, d); 
    reg reg_q; 
    assign q = reg_q; // Blocking style 
    always @(posedge clk) begin 
    reg_q <= d; 
    end 
endmodule 

兩者之間,沒有功能差異。它主要是編碼偏好。有一隻手模擬器不能強制輸入和輸出,所以如果偶然有兩個模塊驅動同一個網絡,這些模擬器X可以將X傳播到寄存器output reg。這是一種罕見的情況,大多數模擬器(特別是主流模擬器)都沒有這個問題。

我個人更喜歡output reg,主要是因爲它的代碼行較少。

不管輸出類型的聲明方式,當實例化模塊,輸出需要被連接到網型(例如wire),而不是一個reg。輸入可以是任何一種類型。

module fifo(output out, input clk, in); 
    wire q0; 
    reg q1; 
    my_dff dff0 (q0, clk, in); 
    always @(posedge clk) begin 
    q1 <= q0; 
    end 
    my_dff dff1 (out, clk, q1); 
endmodule 
1

我假設你正在尋找的東西是這樣的:

module module_b (...); 
    .... 
    module_a foo (.output_a(some_wire), 
        ...); 
endmodule 

如果是這樣的話,那麼也沒有關係 - 這兩個版本同樣會產生導致電路。

第一種方法確實有一些優點,即如果您願意,您可以選擇輸出(類似於assign output_a = valid ? register_a : 0;),並且如果爲您定義的接口能夠在內部使用您選擇的名稱工作(如預設引腳映射)。

如果你不想這樣做,這可能是不正確的。

0

我讀到輸出應該總是被註冊。也就是說module_a有一個名爲output_a的輸出。這是一種行爲與順序的代碼風格。確實,您可以創建相同的硬件,但我認爲您的問題的答案是您應該將輸出聲明爲reg。

因此模塊聲明將是這樣的:

module module_a (output reg output_a); 
.... 
output_a <= "some value" 
endmodule 
+0

註冊重要塊的輸出(例如,頂層塊或將單獨合成的塊)是一種很好的做法。通過「寄存器」,這意味着通過一個觸發器(而不是Verilog'reg')傳遞這些輸出。沒有必要註冊每個模塊的輸出。然而,更重要的是,verilog「reg」不是**觸發器。所以,如果你確實認爲是這樣,請解散你的想法。 –

+0

觸發器是說使用內存是否正確?記憶是什麼?我會做一些進一步的研究,看看是不是這種情況,但是當你總是涉及一個塊時,這是一個很好的練習。但是我排除了頂部答案中的差異,那就是有一個連續的任務。爲什麼然後去時鐘上的任務?這種做法違背了目的,所以在代碼約定方面存在差異。 – Michael

+0

@Micahel不,這是不正確的。 'reg'是一個Verilog變量(與「wire」是網絡相反)。 reg就像任何其他語言的變量一樣:分配給它的最後一個值就是它的值。您可以使用「reg」來推斷組合邏輯或順序邏輯。 –