在设计中,很多情况下,需要编写很多结构相同而参数不同的赋值语句或者逻辑语句,如果参数量很大的情况下,原本的列举就会显得心有余而力不足。c语言中常用for语句来解决此类问题,verilog则为我们提供了generate语句。
generate语句的最主要功能就是对module,reg,assign,always,task等语句或者模块进行复制。
generate语句有generate_for,generate_if,generate_case三种语句。
注意:
(1)必须使用genvar申明一个正整数变量,用做for循环的判断。(genvar是generate语句中的一种变量类型,用在generate_for中声明正整数变量)
(2)需要复制的语句必须写到begin_end语句里面。就算只有一句。
(3)begin_end需要有一个类似于模块名的名字。
例1,利用generate_for来复制assign语句
module generate_for(
input [7:0]data_in,
output [1:0]t0,
output [1:0]t1,
output [1:0]t2,
output [1:0]t3
);
wire [1:0]temp[3:0];//定义位宽为2,深度为4的temp
genvar i;
generate
for(i=0;i<4;i=i+1)
begin:gfor
assign temp[i]=data_in[2*i+1:2*i];
end
endgenerate
assign t0=temp[0];
assign t1=temp[1];
assign t2=temp[2];
assign t3=temp[3];
endmodule
`timescale 1ns/1ps
module tb;
reg [7:0]data_in;
wire [1:0]t0;
wire [1:0]t1;
wire [1:0]t2;
wire [1:0]t3;
initial
begin
data_in=8'd0;
#200;
data_in=8'b1100_0011;
#200;
data_in=8'b0011_1100;
#300;
end
generate_fro generate_inst(
.data_in(data_in),
.t0(t0),
.t1(t1),
.t2(t2),
.t3(t3)
);
endmodule
generate_for用于复制模块,二generate_if则是根据模块的参数(必须是常量)作为条件判断,来产生满足条件的电路。相当于判断语句。
module generate_if(
input t0,
input t1,
input t2,
output d
);
localparam S=6;
generate
if(S<7)
assign d=t0|t1|t2;
else
assign d=t0&t1&t2;
endgenerate
endmodule
由上面我们可以看出模块参数不同,选择的电路就不相同。
generate_case其实和generate_if一样,都是根据参数(都必须为常量)作为判断条件,来产生满足条件的电路,不同于使用了case语法而已。
module generate_case(
input t0,
input t1,
input t2,
output d
);
localparam S=8;
generate
case(S)
0:
assign d=t0|t1|t2;
1:
assign d=t0&t1&t2;
default:
assign d=t0&t1|t2;
endcase
endgenerate
endmodule