一: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例子:

generate
genvar i; //generate 8 samll fifo for in_data[i] 8X72
for(i=0; i<NUM_QUEUES; i=i+1) begin: in_arb_queues //NUM_QUEUES = 8
small_fifo
#( .WIDTH(DATA_WIDTH+CTRL_WIDTH),
.MAX_DEPTH_BITS(2))
in_arb_fifo
(// Outputs
.dout ({fifo_out_ctrl[i], fifo_out_data[i]}),
.full (),
.nearly_full (nearly_full[i]),
.prog_full (),
.empty (empty[i]),
// Inputs
.din ({in_ctrl[i], in_data[i]}),
.wr_en (in_wr[i]),
.rd_en (rd_en[i]),
.reset (reset),
.clk (clk));
end // block: in_arb_queues
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[8i+:8]
this is the so-called “Indexed vector part selects”
在Verilog-1995中,可以选择向量的任一位输出,也可以选择向量的连续几位输出,不过此时连续几位的始末数值的index需要是常量。而在Verilog-2001中,可以用变量作为index,进行part select。
[baseexpr +: widthexpr] positive offset [baseexpr -: widthexpr] negative offset 其中baseexpr可以是变量,而widthexpr必须是常量。+:表示由baseexpr向上增长widthexpr位,-:表示由baseexpr向上递减widthexpr位。例如:
<code verilog> reg [63:0] word; reg [3:0] bytenum; a value from 0 to 7 wire [7:0] byteN = word[bytenum*8 +: 8]; </code> 如果bytenum的值为4,则word[39:32]赋值给byteN
二、参数传递
类似VHDL的Generic语句,Verilog也可以在例化时传递参数
传递的参数是子模块中定义的parameter。
传递的方法:
- modulename #( parameter1, parameter2) instname( portmap); - modulename #( .parametername(paravalue), .parametername(paravalue)) instname (port map); 用#方法和port map的写法差不多
<code verilog> module multiplier (a, b, product); parameter a
width = 8, bwidth = 8; localparam productwidth = awidth+bwidth; input [awidth-1:0] a; input [bwidth-1:0] b; output[productwidth-1:0]product; generate if1) CLAmultiplier #(awidth, bwidth) u1 (a, b, product); else WALLACEmultiplier #(awidth, b_width) u1 (a, b, product); endgenerate endmodule </code>

1) awidth < 8) || (bwidth < 8