Verilog generate循環

一:generate

Verilog-2001添加了generate循環,允許產生module和primitive的多個實例化,同時也可以產生多個variable,net,task,function,continous assignment,initial和always。在generate語句中可以引入if-else和case語句,根據條件不同產生不同的實例化。
用法:

  1. generate語法有generate for, genreate if和generate case三種
  2. generate for語句必須有genvar關鍵字定義for的變量
  3. for 的內容必須加begin和end
  4. 必須給for語段起個名字

(1)generate for例子:


genvar S_i;
generate
for(S_i=0;S_i<C_COEF_NUM;S_i=S_i+1)   //parallel calculation  並行計算
begin:test
wire [C_PRIMPOLY_ORDER-1:0] S_para1;
reg [C_DWIDTH-1:0] S_para2;
localparam C_POLY = C_GEN_POLY [S_i*C_PRIMPOLY_ORDER+:C_PRIMPOLY_ORDER];//每次15bit,從低位到高位
localparam C_UPP  = C_GEN_UPP  [S_i*C_UPP_WIDTH+:C_UPP_WIDTH]-1;//每次4bit,從低位到高位 C_UPP = 14

always @(posedge I_clk)
   begin
      if(I_rst)
         S_para2 <= 'd0;
      else 
	     S_para2 <= I_data;
   end

assign S_para1 = S_data_sof ? 'd0 : S_reg[S_i];

always @(posedge I_clk)
   begin
      if(S_data_v) begin	   
		    S_reg[S_i] <= F_reg_update(S_para1,S_para2,C_POLY,C_UPP);
	   end	
   end

end
endgenerate

(2) generate if例子:

generate
if (REG_WIDTH == WRITE_WIDTH) begin : new_data_a_generation
assign new_data_a = merge_update ? merge_wr_data : held_wr_data_a;
end
else begin
assign new_data_a = merge_update ?
{{(REG_WIDTH - WRITE_WIDTH - 1){merge_wr_data_sign}}, merge_wr_data} :
{{(REG_WIDTH - WRITE_WIDTH){held_wr_data_sign_a}}, held_wr_data_a};
end
endgenerate

3.generate還可以進行多個assign賦值!

module anytest_v(
input clk,
input[7:0] datain,
output[7:0] dataout,
output finish
);
wire[7:0] mem[31:0];
wire[32*8-1:0] xxx;
//reg[7:0] i;
generate
genvar i;
for(i=0;i<=31;i=i+1)
begin :wiertech
assign mem[i]= 8'b0;
end
endgenerate
endmodule
ps

: 對於a[8*i+:8]
this is the so-called “Indexed vector part selects”
在Verilog-1995中,可以選擇向量的任一位輸出,也可以選擇向量的連續幾位輸出,不過此時連續幾位的始末數值的index需要是常量。而在Verilog-2001中,可以用變量作爲index,進行part select。

[base_expr +: width_expr] //positive offset
[base_expr -: width_expr] //negative offset

其中base_expr可以是變量,而width_expr必須是常量。+:表示由base_expr向上增長width_expr位,-:表示由base_expr向上遞減width_expr位。例如:

reg [63:0] word;
reg [3:0] byte_num; //a value from 0 to 7
wire [7:0] byteN = word[byte_num*8 +: 8];

如果byte_num的值爲4,則word[39:32]賦值給byteN
二、參數傳遞
類似VHDL的Generic語句,Verilog也可以在例化時傳遞參數
傳遞的參數是子模塊中定義的parameter。
傳遞的方法:

1、module_name #( parameter1, parameter2) inst_name( port_map);
2、module_name #( .parameter_name(para_value), .parameter_name(para_value)) inst_name (port map);

用#方法和port map的寫法差不多

module multiplier (a, b, product);
parameter a_width = 8, b_width = 8;
localparam product_width = a_width+b_width;
input [a_width-1:0] a;
input [b_width-1:0] b;
output[product_width-1:0]product;
generate
if((a_width < 8) || (b_width < 8))
CLA_multiplier #(a_width, b_width) u1 (a, b, product);
else
WALLACE_multiplier #(a_width, b_width) u1 (a, b, product);
endgenerate
endmodule
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章