天天看點

generae 在Verilog中的使用

Verilog-2001之generate語句的用法

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語句必需用genvar關鍵字定義for的索引變量;

②for的内容必須用begin…end塊包起來,哪怕隻有一句;

③begin…end塊必須起個名字;

例1:一個參數化的gray-code to binary-code 轉換器;這裡采用複制産生多個assign語句的形式來實作;

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:bit

assign bin[i] = ^gray[SIZE-1:i];

end

endgenerate

endmodule
           

等同于下面的語句:

assign bin[0] = ^gray[SIZE-1:0];

assign bin[1] = ^gray[SIZE-1:1];

assign bin[2] = ^gray[SIZE-1:2];

assign bin[3] = ^gray[SIZE-1:3];

assign bin[4] = ^gray[SIZE-1:4];

assign bin[5] = ^gray[SIZE-1:5];

assign bin[6] = ^gray[SIZE-1:6];

assign bin[7] = ^gray[SIZE-1:7];
           

例2:還是例1的gray-code to binary-code 轉換器;不過這裡采用複制産生多個always語句的形式來實作;

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];
           

例3:一個行波進位加法器,在begin…end内部定義局部變量,并且在generate語句内定義genvar變量;

moduleaddergen1 (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;

assign c[0] = ci;

generate

genvar i;

for(i=0; i<SIZE; i=i+1)

begin:bit

wiret1, t2, t3; // generated net declaration

xorg1 (t1, a[i], b[i]);

xorg2 (sum[i], t1, c[i]);

andg3 (t2, a[i], b[i]);

andg4 (t3, t1, c[i]);

org5 (c[i+1], t2, t3);

end

endgenerate

assign co = c[SIZE];

endmodule
           

等同于下面的語句:

wire bit[0].t1, bit[0].t2, bit[0].t3;

xor bit[0].g1 (bit[0].t1, a[0], b[0]);

xor bit[0].g2 (sum[0], bit[0].t1, c[0]);

and bit[0].g3 (bit[0].t2, a[0], b[0]);

and bit[0].g4 (bit[0].t3, bit[0].t1, c[0]);

or bit[0].g5 (c[0+1], bit[0].t2, bit[0].t3);

wire bit[1].t1, bit[1].t2, bit[1].t3;

xor bit[1].g1 (bit[1].t1, a[1], b[1]);

xor bit[1].g2 (sum[1], bit[1].t1, c[1]);

and bit[1].g3 (bit[1].t2, a[1], b[1]);

and bit[1].g4 (bit[1].t3, bit[1].t1, c[1]);

or bit[1].g5 (c[1+1], bit[1].t2, bit[1].t3);

wire bit[2].t1, bit[2].t2, bit[2].t3;

xor bit[2].g1 (bit[2].t1, a[2], b[2]);

xor bit[2].g2 (sum[2], bit[2].t1, c[2]);

and bit[2].g3 (bit[2].t2, a[2], b[2]);

and bit[2].g4 (bit[2].t3, bit[2].t1, c[2]);

or bit[2].g5 (c[2+1], bit[2].t2, bit[2].t3);

wire bit[3].t1, bit[3].t2, bit[3].t3;

xor bit[3].g1 (bit[3].t1, a[3], b[3]);

xor bit[3].g2 (sum[3], bit[3].t1, c[3]);

and bit[3].g3 (bit[3].t2, a[3], b[3]);

and bit[3].g4 (bit[3].t3, bit[3].t1, c[3]);

or bit[3].g5 (c[3+1], bit[3].t2, bit[3].t3);
           

這樣,複制産生的執行個體名稱為:

xor gates: bit[0].g1 bit[1].g1 bit[2].g1 bit[3].g1

             bit[0].g2 bit[1].g2 bit[2].g2 bit[3].g2

and gates: bit[0].g3 bit[1].g3 bit[2].g3 bit[3].g3

             bit[0].g4 bit[1].g4 bit[2].g4 bit[3].g4

or gates: bit[0].g5 bit[1].g5 bit[2].g5 bit[3].g5
           

複制産生的wire組為:

bit[0].t1 bit[1].t1 bit[2].t1 bit[3].t1

bit[0].t2 bit[1].t2 bit[2].t2 bit[3].t2

bit[0].t3 bit[1].t3 bit[2].t3 bit[3].t3
           

可見,給begin…end塊命名的用途!

例4:一個行波進位加法器,使用外部定義的變量,這樣就不會對外部變量做變動;

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;

wire [SIZE-1:0] t [1:3];

genvar i;

assign c[0] = ci;

generate

for(i=0; i<SIZE; i=i+1)

begin:bit

xorg1 ( t[1][i], a[i], b[i]);

xorg2 ( sum[i], t[1][i], c[i]);

andg3 ( t[2][i], a[i], b[i]);

andg4 ( t[3][i], t[1][i], c[i]);

org5 ( c[i+1], t[2][i], t[3][i]);

end

endgenerate

assign co = c[SIZE];

endmodule
           

這樣,複制産生的執行個體名稱為:

xor gates: bit[0].g1 bit[1].g1 bit[2].g1 bit[3].g1

bit[0].g2 bit[1].g2 bit[2].g2 bit[3].g2

and gates: bit[0].g3 bit[1].g3 bit[2].g3 bit[3].g3

bit[0].g4 bit[1].g4 bit[2].g4 bit[3].g4

or gates: bit[0].g5 bit[1].g5 bit[2].g5 bit[3].g5
           

而外部變量t與a,b,sum等一樣,沒有複制産生新的變量組

例5:多層generate語句所複制産生的執行個體命名方式;

parameterSIZE = 2;

genvari, 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
           

generate-if語.

根據條件不同産生不同的執行個體化,即根據子產品參數(.量)的條件是否滿足來選擇其中一段代碼生成相應的電路,例如

ifdef …elsif else …endif;

例1:

module generate_if (a,b,c,y);

input a,b,c;

output y;

localparam SIZE = 12;// 參數常量

generate

if (SIZE < 8)

assign y = a & b & c;

else if (SIZE == 8)

assign y = a & b | c;

else

assign y = a | b | c;// 最後該語句生成電路;

endgenerate

endmodule
           

例2:

module multiplier(a,b,product);

parameter a_width = 8, b_width = 8;

localparam product_width = a_width+b_width; 

// localparamcan not be modifieddirectly with thedefparamstatementor 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))

CLA_multiplier #(a_width,b_width) u0(a, b, product);

// instantiate a CLA multiplier

else

WALLACE_multiplier #(a_width,b_width)u1(a,b,product);

// instantiate a Wallace-tree multiplier

endgenerate

// The generated instance name is u1

endmodule
           

注意:這裡的條件都是常量條件,非常量條件不能綜合;

generate-case語.

跟generate-if語句一樣的用法,隻是采用case語句的形式

例1:

generate

case(WIDTH)

1: adder_1bit x1(co, sum, a, b, ci);

// 1-bit adder implementation

2: adder_2bit x1(co, sum, a, b, ci);

// 2-bit adder implementation

default: adder_cla #(WIDTH) x1(co, sum, a, b, ci);

// others -carry look-ahead adder

endcase

// The generated instance name is x1

endgenerate
           

原文位址