SV——generate constructs

0. 介绍

​ generate构建是用来例化一个或者多个generate block;generate block可以是module item、一段语句或者嵌套的generate block。但不能有端口声明。

​ generate 调度是在elaboration阶段,而不是在simulation。generate scheme的结果在simulation之前就确定了。所有在generate scheme阶段的表达式都应该是常量表达式。

​ 可以用generate……endgenerate关键字,当然也可以不用。

​ generate constructs有两种loop generate constructs 和conditional generate constructs。

1. loop generate constructs

​ 在循环生成中,一个generate block被重复生成多次。循环的索引变量应该被声明为genvar

The genvar is used as an integer during elaboration to evaluate the generate loop and create instances of the generate block, but it does not exist at simulation time. A genvar shall not be referenced anywhere other than in a loop generate scheme.

注意:

  1. 嵌套的循环生成中,不同的generate的genvar变量名不能相同。
  2. 如果generate block被命名,那么名字不能和关键字、其他变量名重合,最好也不要和其他的block name重合。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// A parameterized gray-code–to–binary-code converter module using a loop to generate continuous assignments
module gray2bin1 (bin, gray);
parameter SIZE = 8; // this module is parameterizable
output [SIZE-1:0] bin;
input [SIZE-1:0] gray;
genvar i;
generate
for (i=0; i<SIZE; i=i+1) begin:bitnum
assign bin[i] = ^gray[SIZE-1:i];
// i refers to the implicitly defined localparam whose
// value in each instance of the generate block is
// the value of the genvar when it was elaborated.
end
endgenerate
endmodule
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
module addergen1 (co, sum, a, b, ci);
parameter SIZE = 4;
output [SIZE-1:0] sum;
output co;
input [SIZE-1:0] a, b;
input ci;
wire [SIZE :0] c;
genvar i;
assign c[0] = ci;

for(i=0; i<SIZE; i=i+1) begin:bitnum
wire t1, t2, t3;
xor g1 ( t1, a[i], b[i]);
xor g2 ( sum[i], t1, c[i]);
and g3 ( t2, a[i], b[i]);
and g4 ( t3, t1, c[i]);
or g5 ( c[i+1], t2, t3);
end
assign co = c[SIZE];
endmodule

2. conditional generate constructs

The conditional generate constructs, if-generate and case-generate, select at most one generate block from a set of alternative generate blocks based on constant expressions evaluated during elaboration.

​ 可以通过if–else、case来进行条件判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 通过if--else判断
module multiplier(a,b,product);
parameter a_width = 8, b_width = 8;
localparam product_width = a_width+b_width;
// cannot be modified directly with the defparam
// statement or the module instance statement #
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)) begin: mult
CLA_multiplier #(a_width,b_width) u1(a, b, product);
// instantiate a CLA multiplier
end
else begin: mult
WALLACE_multiplier #(a_width,b_width) u1(a, b, product);
// instantiate a Wallace-tree multiplier
end
endgenerate
// The hierarchical instance name is mult.u1
endmodule
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 通过case判断
generate
case (WIDTH)
1: begin: adder // 1-bit adder implementation
adder_1bit x1(co, sum, a, b, ci);
end
2: begin: adder // 2-bit adder implementation
adder_2bit x1(co, sum, a, b, ci);
end
default:
begin: adder // others - carry look-ahead adder
adder_cla #(WIDTH) x1(co, sum, a, b, ci);
end
endcase
// The hierarchical instance name is adder.x1
endgenerate