比方說module_a
有register_a
,它需要鏈接到module_b
。應該register_a
另行申報,並分配給module_a
輸出:Verilog中的模塊:輸出寄存器與賦值寄存器到導線輸出
reg register_a;
assign output_a = register_a;
或者我們應該申報output_a
與在模塊聲明一個reg
內聯和使用的代碼?
比方說module_a
有register_a
,它需要鏈接到module_b
。應該register_a
另行申報,並分配給module_a
輸出:Verilog中的模塊:輸出寄存器與賦值寄存器到導線輸出
reg register_a;
assign output_a = register_a;
或者我們應該申報output_a
與在模塊聲明一個reg
內聯和使用的代碼?
我想你問的是下面的區別:
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
我假設你正在尋找的東西是這樣的:
module module_b (...);
....
module_a foo (.output_a(some_wire),
...);
endmodule
如果是這樣的話,那麼也沒有關係 - 這兩個版本同樣會產生導致電路。
第一種方法確實有一些優點,即如果您願意,您可以選擇輸出(類似於assign output_a = valid ? register_a : 0;
),並且如果爲您定義的接口能夠在內部使用您選擇的名稱工作(如預設引腳映射)。
如果你不想這樣做,這可能是不正確的。
我讀到輸出應該總是被註冊。也就是說module_a有一個名爲output_a的輸出。這是一種行爲與順序的代碼風格。確實,您可以創建相同的硬件,但我認爲您的問題的答案是您應該將輸出聲明爲reg。
因此模塊聲明將是這樣的:
module module_a (output reg output_a);
....
output_a <= "some value"
endmodule
註冊重要塊的輸出(例如,頂層塊或將單獨合成的塊)是一種很好的做法。通過「寄存器」,這意味着通過一個觸發器(而不是Verilog'reg')傳遞這些輸出。沒有必要註冊每個模塊的輸出。然而,更重要的是,verilog「reg」不是**觸發器。所以,如果你確實認爲是這樣,請解散你的想法。 –
觸發器是說使用內存是否正確?記憶是什麼?我會做一些進一步的研究,看看是不是這種情況,但是當你總是涉及一個塊時,這是一個很好的練習。但是我排除了頂部答案中的差異,那就是有一個連續的任務。爲什麼然後去時鐘上的任務?這種做法違背了目的,所以在代碼約定方面存在差異。 – Michael
@Micahel不,這是不正確的。 'reg'是一個Verilog變量(與「wire」是網絡相反)。 reg就像任何其他語言的變量一樣:分配給它的最後一個值就是它的值。您可以使用「reg」來推斷組合邏輯或順序邏輯。 –