Verilog:generate、for、always 語句用法與電路結構對比
文章目錄
最近寫Verilog時,對於generate-for 和 for迴圈相關不是很清楚,所以寫了一些程式碼對比一下不同寫法的結果,記錄一下,如有錯誤請多多指正,不喜輕噴。
1、always-for
程式碼:
reg [data_width-1:0] in1_reg [0:depth-1]; integer i; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin for(i=0;i<depth;i=i+1) in1_reg[i] <= 0; end else begin for(i=0;i<depth;i=i+1) in1_reg[i] <= in1+i; end end
模擬結果說明:in1_reg 在第一個有效時鐘沿後,資料均變為目標值
ANALYSIS得到的結構圖
綜合後的電路圖:
2、 for-always
程式碼:
//integer j; // Error:j is not a genvar;j is not a constant genvar j; reg [data_width-1:0] in2_reg [0:depth-1]; for(j=0;j<depth;j=j+1) begin:in2_loop always@(posedge clk or negedge rst_n) begin if(!rst_n) in2_reg[j] <= 0; else in2_reg[j] <= in2+j; end end
模擬結果說明:in2_reg 在第一個有效時鐘沿後,資料均變為目標值
ANALYSIS得到的結構圖
綜合後的電路圖:
3、generate_for_always
程式碼:
reg [data_width-1:0] in3_reg [0:depth-1]; genvar k; generate for(k=0;k<depth;k=k+1) begin:generate_case always@(posedge clk or negedge rst_n) begin if(!rst_n) in3_reg[k] <= 0; else in3_reg[k] <= in3+k; end end endgenerate
模擬結果說明:in3_reg 在第一個有效時鐘沿後,資料均變為目標值
ANALYSIS得到的結構圖
綜合後的電路圖:
3.1、generate-always-for
程式碼:
reg [data_width-1:0] in31_reg [0:depth-1];
//genvar k1; // Error:procedural assignment to a non-register k1 is not permitted, left-hand side should be reg/integer/time/genvar
integer k1;
generate
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
for(k1=0;k1<depth;k1=k1+1)
begin:for_rst
in31_reg[k1] <= 0;
end
end
else
begin
for(k1=0;k1<depth;k1=k1+1)
begin:generate_always_for
in31_reg[k1] <= in31+k1;
end
end
end
endgenerate
模擬結果說明:in31_reg 在第一個有效時鐘沿後,資料均變為目標值
ANALYSIS得到的結構圖
綜合後的電路圖:
4、for-assign
程式碼:
wire[data_width-1:0] in4_wire [0:depth-1];
//integer n; // Error: n is not a genvar;n is not a constant
genvar n;
for(n=0;n<depth;n=n+1)
begin:for_assign
assign in4_wire[n] = in4+n;
end
模擬結果說明:wire型,模擬開始即有值,隨輸入訊號變化而變化
ANALYSIS得到的結構圖
綜合後的電路圖:
5、generate-for-assign
程式碼:
wire[data_width-1:0] in5_wire [0:depth-1];
genvar m;
generate
for(m=0;m<depth;m=m+1)
begin:generate_for_assign
assign in5_wire[m] = in5+m;
end
endgenerate
模擬結果說明:wire型,模擬開始即有值,隨輸入訊號變化而變化
ANALYSIS得到的結構圖
綜合後的電路圖:
6、always@(*)-for
程式碼:
reg [data_width-1:0] in6_reg [0:depth-1];
always@(*)
begin
for(i=0;i<depth;i=i+1)
in6_reg[i] = in6+i;
end
模擬結果說明:wire型,模擬開始即有值,隨輸入訊號變化而變化
ANALYSIS得到的結構圖
綜合後的電路圖:
7、for-always@(*)
可以用 for-assign 替換
8、generate_for_always@(*)
可以用generate-assign 替換
模擬結果
可以看到,時序訊號in1_reg,in2_reg,in3_reg,in31_reg 都在第一個有效時鐘邊沿後變為目標值;組合邏輯訊號in4_wire, in5_wire, in6_reg 在電路開始模擬時即被賦值進行運算,輸入資料變化後隨之發生變化
2、根據電路結構,generate-for 和 for 迴圈對於always 和 assig 語句的作用相同,但書寫方法不同
generate-for / for迴圈在alway塊外面時,迴圈變數要定義為 genvar 型
for 迴圈在always 塊內時,迴圈遍歷要定義為 integer 型別
3、結論:
若要在迴圈/條件/分支語句中呼叫模組,須使用 generate-for語句,注意要用genvar 定義迴圈變數,並在for迴圈的 begin: 後跟上 迴圈名稱;
其他情況可根據自身情況而定
generate-for和for迴圈使用說明可見 Verilog:generate-for 語句(用法,及與for語句區別)
文中的程式碼等可見https://download.csdn.net/download/weixin_44544687/13117406