条件generate结构体(if-generate和case-generate)根据elaboration过程中评估的常量表达式,从一组可供选择的generate块中最多选择一个generate块,被选中的generate块(如果有的话)将被例化。
条件generate结构中的generate块可以命名,也可以不命名,它们可以只由一个条目组成,在这种情况先不需要用 begin/end 关键字围绕。即使没有 begin/end 关键字,它仍然是一个generate块,与所有generate块一样,它在实例化时包含一个独立的作用域和一个新的层级结构。
由于最多只能例化某一个generate块,因此允许在一个条件generate结构体中存在多个同名块。不允许任何已命名的generate块与同一作用域中任何其他条件generate结构体或循环结构体中的generate块同名,即使未选择同名块进行例化。不允许任何已命名的generate块与同一作用域中的任何其他声明具有相同名称,即使该块未被选中进行实例化。
如果被选中进行例化的generate块已被命名,那么该名称将声明一个生generate块实例,并成为它所创建的作用域的名称。如果被例化的generate块没有命名,那么它仍然会创建一个作用域;但其中的声明不能使用层级结构名称来引用,只能从generate块本身例化的层级结构中引用。
最常见的用法是创建一个包含任意数量 else-if 子句的 if-else-if generate方案,所有这些子句都可以有相同名称的generate块,因为只有一个会被选中进行实例化。 在同一个复杂的generate方案中,允许结合 if-generate 和 case-generate 结构。下面举几个例子来说明 条件generate结构体的用法:
例子1:
module test;
parameter p = 0, q = 0;
wire a, b, c;
//---------------------------------------------------------
// Code to either generate a u1.g1 instance or no instance.
// The u1.g1 instance of one of the following gates:
// (and, or, xor, xnor) is generated if
// {p,q} == {1,0}, {1,2}, {2,0}, {2,1}, {2,2}, {2, default}
//---------------------------------------------------------
if (p == 1)
if (q == 0)
begin : u1 // If p==1 and q==0, then instantiate
and g1(a, b, c); // AND with hierarchical name test.u1.g1
end
else if (q == 2)
begin : u1 // If p==1 and q==2, then instantiate
or g1(a, b, c); // OR with hierarchical name test.u1.g1
end
// "else" added to end "if (q == 2)" statement
else ; // If p==1 and q!=0 or 2, then no instantiation
else if (p == 2)
case (q)
0, 1, 2:
begin : u1 // If p==2 and q==0,1, or 2, then instantiate
xor g1(a, b, c);// XOR with hierarchical name test.u1.g1
end
default :
begin : u1 // If p==2 and q!=0,1, or 2, then instantiate
xnor g1(a, b, c);// XNOR with hierarchical name test.u1.g1
end
endcase
endmodule
例 2-参数化d 乘法器模块实现:
例 3-case-generate语句,以处理位宽小于3的情况:
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
例 4--内存模块
module dimm(addr, ba, rasx, casx, csx, wex, cke, clk, dqm, data, dev_id);
parameter [31:0] MEM_WIDTH = 16, MEM_SIZE = 8; // in mbytes
input [10:0] addr;
input ba, rasx, casx, csx, wex, cke, clk;
input [ 7:0] dqm;
inout [63:0] data;
input [ 4:0] dev_id;
genvar i;
case ({MEM_SIZE, MEM_WIDTH})
{32'd8, 32'd16}: // 8Meg x 16 bits wide
begin : memory
for (i=0; i<4; i=i+1) begin :word
sms_08b216t0 p(.clk(clk), .csb(csx), .cke(cke),.ba(ba),
.addr(addr), .rasb(rasx), .casb(casx),
.web(wex), .udqm(dqm[2*i+1]), .ldqm(dqm[2*i]),
.dqi(data[15+16*i:16*i]), .dev_id(dev_id));
// The hierarchical instance names are memory.word[3].p,
// memory.word[2].p, memory.word[1].p, memory.word[0].p,
// and the task memory.read_mem
end
task read_mem;
input [31:0] address;
output [63:0] data;
begin // call read_mem in sms module
word[3].p.read_mem(address, data[63:48]);
word[2].p.read_mem(address, data[47:32]);
word[1].p.read_mem(address, data[31:16]);
word[0].p.read_mem(address, data[15: 0]);
end
endtask
end
{32'd16, 32'd8}: // 16Meg x 8 bits wide
begin : memory
for (i=0; i<8; i=i+1) begin :byte
sms_16b208t0 p(.clk(clk), .csb(csx), .cke(cke),.ba(ba),
.addr(addr), .rasb(rasx), .casb(casx),
.web(wex), .dqm(dqm[i]),
.dqi(data[7+8*i:8*i]), .dev_id(dev_id));
// The hierarchical instance names are memory.byte[7].p,
// memory.byte[6].p, ... , memory.byte[1].p, memory.byte[0].p,
// and the task memory.read_mem
end
task read_mem;
input [31:0] address;
output [63:0] data;
begin // call read_mem in sms module
byte[7].p.read_mem(address, data[63:56]);
byte[6].p.read_mem(address, data[55:48]);
byte[5].p.read_mem(address, data[47:40]);
byte[4].p.read_mem(address, data[39:32]);
byte[3].p.read_mem(address, data[31:24]);
byte[2].p.read_mem(address, data[23:16]);
byte[1].p.read_mem(address, data[15: 8]);
byte[0].p.read_mem(address, data[ 7: 0]);
end
endtask
end
// Other memory cases ...
endcase
endmodule
点赞加关注博主(ID:FPGA小飞)的博文,咱们一起系统学习verilog最终标准IEEE Std 1364-2005吧!