Verilog-1995 支持通过以声明实例数组的形式对primitive和module进行复制结构建模。而在Verilog-2001里,新增加的generate语句拓展了这种用法(其思想来源于VHDL语言)。除了允许复制产生primitive和module的多个实例化,同时也可以复制产生多个net、reg、parameter、assign、always、initial、task、function。
在generate中引入了一种新的变量类型:genvar,用以在generate-for语句中声明一个正整数的索引变量(如果将“X”或“Z”或者“负值”赋给genvar 变量,将会出错)。genvar 变量可以声明在generate语句内,也可以声明在generate语句外。 (摘自百度文库,对于对于这些语言的标准我觉得没必要去细究,知道用法就行了)
generate语句有generate-for、genreate-if和generate-case三种语句。由于我遇到的常用的就是generate-for语句,这里我就记下generate-for语句的用法。
exp1:
module gray2bin2 (bin, gray);
parameter SIZE = 8; // this module is parameterizable output [SIZE-1:0] bin;
input [SIZE-1:0] gray;
reg [SIZE-1:0] bin;
genvar i;
generate
for(i=0; i<SIZE; i=i+1)
begin: bit
always @(gray[SIZE-1:i]) // fixed part select
bin[i] = ^gray[SIZE-1:i];
end
endgenerate
endmodule 等同于下面的语句:
always @(gray[SIZE-1:0]) // fixed part select
bin[0] = ^gray[SIZE-1:0];
always @(gray[SIZE-1:1]) // fixed part select
bin[1] = ^gray[SIZE-1:1];
always @(gray[SIZE-1:2]) // fixed part select
bin[2] = ^gray[SIZE-1:2];
always @(gray[SIZE-1:3]) // fixed part select
bin[3] = ^gray[SIZE-1:3];
always @(gray[SIZE-1:4]) // fixed part select
bin[4] = ^gray[SIZE-1:4];
always @(gray[SIZE-1:5]) // fixed part select
bin[5] = ^gray[SIZE-1:5];
always @(gray[SIZE-1:6]) // fixed part select
bin[6] = ^gray[SIZE-1:6];
always @(gray[SIZE-1:7]) // fixed part select
bin[7] = ^gray[SIZE-1:7];
此例程中用到的是always语句,generate-for语句起到的作用很明显,就是代码的复制,也可以说是逻辑的复制。
exp2:多层generate语句所复制产生的实例命名方式;
parameter SIZE = 2; genvar i, j, k, m;
generate
for(i=0; i<SIZE; i=i+1)
begin: B1 // scope B1[i]
M1 N1();// instantiates B1[i].N1
for(j=0; j<SIZE; j=j+1)
begin: B2 // scope B1[i].B2[j]
M2 N2();// instantiates B1[i].B2[j].N2
for(k=0; k<SIZE; k=k+1)
begin: B3 // scope B1[i].B2[j].B3[k]
M3 N3(); // instantiates B1[i].B2[j].B3[k].N3
end
end
if(i>0)
for(m=0; m<SIZE; m=m+1)
begin: B4 // scope B1[i].B4[m]
M4 N4(); // instantiates B1[i].B4[m].N4
end
end
endgenerate
下面是复制产生的实例名称的几个例子: B1[0].N1 B1[1].N1
B1[0].B2[0].N2 B1[0].B2[1].N2
B1[0].B2[0].B3[0].N3 B1[0].B2[0].B3[1].N3 B1[0].B2[1].B3[0].N3
B1[1].B4[0].N4 B1[1].B4[1].N4
在这里大家需要注意的就是实例产生后的名称。第一级循环在最前,然后依次往后排列就行了。
Verilog中参数传递用法
直接上例子说明吧。
底层模块中:
module A #(
parameter a = 32'd0,
b = 32'd0
)
(
input clk,
output cnt
)
......
......
endmodule
其中a,b为定义的底层模块的参数,默认值为32'd0.
在顶层模块中调用:
A #(
.a (32'd1),
.b (32'd1)
)
A_inst1(
.clk (XX),//接顶层模块信号
.cnt (XX)
);
A #(
.a (32'd2),
.b (32'd2)
)
A_inst2(
.clk (XX),//接顶层模块信号
.cnt (XX)
);
在A_inst1中向底层模块传递的参数值为1,在A_inst2中向底层模块传递的参数值为2.
当然参数传递还有其他的格式,我个人认为这种方式更加清晰明了,所以暂时就用这种了,以后遇到其他情况另说,对于其他的方法我就不做说明了。我觉得这种方法以这种例子的形式来介绍应该很容易理解,希望能帮到需要的同学们吧。