在Verilog-2001中新增了语句generate,通过generate循环,可以产生一个对象(比如一个元件或者是一个模块)的多次例化,为可变尺度的设计提供了方便,generate语句一般在循环和条件语句中使用,为此,Verilog-2001增加了四个关键字generate,endgenerate, genvar, localparam,genvar是一个新增的数据类型,用在generate的循环中的标尺变量必须定义为gnevar类型;
下面举例说明generate的用法:
首先设计一个1bit位宽的buffer_1:
//1bit width buffer_1
module buffer_1(
input wire in,
output wire out
);
assign out = ~in;
endmodule
在buffer_8中例化buffer_1 8次,这里有几点需要注意:
- 循环变量i必须是genvar类型的,不可以是reg型,integer型;
- for循环之后的的begin最好加上一个标号(BLOCK1);
//8bit width buffer
module buffer_8(
input wire[7:0] din,
output wire[7:0] dout
);
// Generate block
genvar i;
generate
for(i=0; i<8; i=i+1) begin:BLOCK1
buffer_1 buffer_1_1(.in(din[i]), .out(dout[i]));
end
endgenerate
endmodule
这里给出了一个简单的顶层:
//testbench
module buffer_8_tb;
// reg & wire define area
reg [7:0] din;
wire[7:0] dout;
// Instance the DUT
buffer_8 buffer_8_1(
.din (din ),
.dout (dout )
);
// Generate the stimulate
initial begin
din = 8'd7;
#10; din = 8'd6;
#10; din = 8'd4;
#10; din = 8'd7;
#10; $finish();
end
endmodule
在generate语句中可以出现以下三种语句:
(1)generate...loop循环语句
(2)generate...case分支语句
(3)generate...conditional条件语句
generate语句的格式如下:
generate
//generate...loop循环语句
//generate...case分支语句
//generate...conditional条件语句
//嵌套的generate语句
endgenerate
1.generate循环语句
generate循环语句被用于(verilog编译)细化阶段的语句复制,允许对结构元素编写一个for循环,下面的例子是一个N位异或门。
module nbit_xor
#(parameter SIZE=16)
(input(SIZE-1:0) a,b,output[SIZE-1:0] y);
genvar gv_i;
generate
for(gv_i=0;gv_i<SIZE;gv_i++)
begin:sblka
xor uxor(y[gv_i],a[gv_i],b[gv_i]);
end
endgenerate
endmodule
for循环中使用的循环变量gv_i被称为genvar变量,这种变量必须用genvar来声明,并且只能在generate循环语句中使用;此外,generate块需要标签,用来表示循环的实例化名称,在上例中是sblka.
2.generate-conditional条件语句
generate条件语句允许在细化期间对语句进行条件选择。generate条件语句最常见的格式如下:
if(condition)
statements
else
statements
condition必须是一个静态的条件,即在细化期间计算的出。statements可以是任何能够在模块中出现的语句,例如always语句。注意,由于条件的值可能取决于从上层模块中传递过来的参数,因此条件的值可能不能再细化期间被完全算出来。下面举一个用generate条件形式的例子:
module adder
#(parameter SIZE=4)
(input[SIZE-1:0] a,b,
output[SIZE-1:0] sum,
output carry_out);
wire [SIZE-1:0] carry;
genvar gv_k;
generate
for(gv_k=0;gv_k<SIZE;gv_k++)
begin: gen_blk_adder
if(gv_k == 0)
half_adder u_ha (.a(a[gv_k]),
.b(b[gv_k]),
.sum(sum[gv_k]),
.carry_out(carry[gv_k]),
);
else
full_adder u_ha (.a(a[gv_k]),
.b(b[gv_k]),
.sum(sum[gv_k]),
.carry_in(carry[gv_k-1]),
.carry_out(carry[gv_k]),
);
end
endgenerate
endmodule
3.generate-case分支语句
generate分支语句与条件语句类似,只不过分支语句是用分支来进行条件选择,给出下面的例子:
module adder
#(parameter SIZE=4
parameter IMPLEMENTATION_LEVEL=0)
(input[SIZE-1:0] arg1,arg2,
output[SIZE-1:0] result,
);
generate
case(IMPLEMENTATION_LEVEL)
0: assign result=arg1+arg2;
1:.....;
2:.....;
3:.....;
default:......;
endgenerate
endmodule