2014-09-19 251 views
4

我想了解爲什麼我們在for循環中使用verilog生成。在verilog中使用for循環生成

使用產生和循環在一起:

reg [3:0] temp; 
genvar i; 
generate 
for (i = 0; i < 3 ; i = i + 1) begin: 
    always @(posedge sysclk) begin 
     temp[i] <= 1'b0; 
    end 
end 
endgenerate 

只使用for循環:

reg [3:0] temp; 
genvar i; 
always @(posedge sysclk) begin 
    for (i = 0; i < 3 ; i = i + 1) begin: 
    temp[i] <= 1'b0; 
    end 
end 

我正在考慮這兩個段將基本產生相同的結果,即溫度[0]到temp [10]等於0.在這種情況下,我們使用generate語句看到的差異/優點是什麼?

+2

你試過編譯這些片段嗎?第二個應該是一個語法錯誤。只有for循環在內部生成時,才能將其始終放在for循環中! – Ari 2014-09-19 00:23:42

+0

你的意思是在always塊中有for循環嗎? – toolic 2014-09-19 00:35:28

+1

'temp'中只有4位。爲什麼你的for循環從0到9?沒有'temp [4]'。 – toolic 2014-09-19 00:41:54

回答

2

在沒有generate的示例中,i應該是genvar而不是integer。否則,兩者都有效,具體取決於工具集支持的IEEE Std 1364的版本。在IEEE Std 1364-2001中增加了生成結構,其中明確需要關鍵字generate/endgenerate。在IEEE Std 1364-2005中,它成爲可選項,唯一的要求是,如果使用generate,它必須具有匹配的endgenerate

當使用IEEE Std 1364-2005或SystemVerilog(IEEE Std 1800)時,隱式與顯式聲明的編碼風格偏好是一個問題。顯式確實具有向後可比性的優點。


當通過參數改變模塊的物理結構時,生成塊很有用。例如選擇negedge或posedge時鐘,只允許一個:

if (param_use_pos == 1) begin : use_pos 
    always @(posedge sysclk) begin 
    ... 
    end 
end 
else begin : use_neg 
    always @(negedge sysclk) begin 
    ... 
    end 
end 

如果不改變物理結構,通常最好使用for循環和if-else語句總是塊內。兩種方法都可以合成相同的結果,但是在運行RTL仿真時,非生成塊方法通常會更快地進行模擬。這是因爲模擬器通常可以比N個1位操作更快地處理單個N位操作。再次合成是相同的結果

// faster :: 1 always block, simulator can optimize the for loop 
always @(posedge sysclk) begin 
    for (i = 0; i < 3 ; i = i + 1) begin 
    temp[i] <= 1'b0; 
    end 
end 

// slower :: creates 4 always blocks, harder for the simulator to optimize 
genvar i; 
generate // optional if > *-2001 
for (i = 0; i < 3 ; i = i + 1) begin 
    always @(posedge sysclk) begin 
     temp[i] <= 1'b0; 
    end 
end 
endgenerate // match generate 
+0

我認爲一個例子展示瞭如何使用generate來創建參數化的實例化,其中for循環可以迭代固定硬件,兩者之間的區別可能更加清晰。 – Morgan 2014-09-19 06:53:47

4

一般而言,產生用於循環和定期for循環之間的主要區別在於,生成用於循環產生用於每次迭代的實例。這意味着在你的例子中會有3個總是塊(相對於常規循環情況下的1塊)。

的代碼一個很好的例子是需要生成是:

module A(); 
.. 
endmodule; 

module B(); 
parameter NUM_OF_A_MODULES = 2; // should be overriden from higher hierarchy 
genvar i; 
for (i=0 i<NUM_OF_A_MODULES; i=i+1) { 
    A A_inst(); 
} 
endmodule; 

在這個例子中一個普通的不能做創建NUM_OF_A_MODULES情況下的工作。

您的示例中,您可以通過兩種方式獲得所需的結果。 (只要你修復一些小錯誤:))