一: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 与always 语句结合使用
genvar i;
generate
for(i = 0; i <MCB_BYTE_WIDTH-1 ;i = i+1)
begin :data_shit
always @( posedge wr_clk )
begin
if(i_h_sync )
begin
data_ram[i+1] <= data_ram[i];
end
end
end
endgenerate
2、gnerate for实现复制
genvar bufds_num;
generate
for ( bufds_num = 0; bufds_num < DATA_WIDTH ; bufds_num = bufds_num + 1)
begin :ibufds_inst
IBUFDS #(.DIFF_TERM(“FALSE”),.IBUF_LOW_PWR(“TRUE”), .IOSTANDARD(“LVDS_25”)
) IBUFDS_inst00 (.O(dout[bufds_num]), .I(din_p[bufds_num]), .IB(din_n[bufds_num]));
end
endgenerate
2、 generate if 用法
parameter TRANS_FLAG = 1’b1;
generate
if(TRANS_FLAG == 1’b1 )
begin:trans_f
always @( posedge rd_clk )
begin
if( rd_cnt >= cfg_rd_cnt-1 )
rd_cnt <=4’d0;
else
rd_cnt <= rd_cnt + 1’b1;
end
always @( posedge rd_clk )
begin
if((empty == 1’b0)&&(rd_cnt == 0))
rd_en <= 1’b1;
else
rd_en <= 1’b0;
end
end
else
begin
always @( posedge rd_clk )
begin
if(empty == 1’b0)//(rd_cnt == 0)//&& )
rd_en <= 1’b1;
else
rd_en <= 1’b0;
end
always @( posedge rd_clk )
begin
if(num == (cfg_len-1)&&out_valid) //( )&&(rd_cnt == cfg_rd_cnt ) )
begin
num <= 5’d0;
end
else if(out_valid)//( rd_cnt == cfg_rd_cnt )
begin
num <= num + 1’b1;
end
else
begin
num <= num;
end
end
always @( posedge rd_clk )
begin
if((num == 5’d0)&& out_valid )
begin
nt_dout <= rd_en;
end
else
begin
nt_dout <= 1’b0;
end
end
always @( posedge rd_clk )
begin
nd_dout <= out_valid;
end
end
endgenerate
二、参数传递
类似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