Verilog中的生成块

        生成语句可以动态地生成Verilog代码。当对矢量中的多个位进行重复操作时,或者当进行多个模块的实例引用的重复操作时,或者在根据参数的定义来确定程序中是否应该包括某段Verilog代码的时候,生成语句的使用方便了参数化模块的生成。

        生成语句能够控制变量的声明、任务或函数的调用,还能对实例引用进行全面的控制。关键字generate-endgenerate来指定生成的实例范围。生成实例可以是以下的一个或多个类型:

        (1)模块;

        (2)用户定义原语;

        (3)门级原语;

        (4)连续赋值语句;

        (5)initial和always块。

 

        1、代码设计中可以多次有条件地调用(实例引用)生成的实例和生成的变量声明,而且生成的实例具有唯一的标识名,可以用层次命名规则引用。

        2、为了支持结构化的元件和过程块语句的相互连接,Verilog语言允许在生成范围内声明下列数据类型:

        (1)net(线网)、reg(寄存器);

        (2)integer(整型数)、real(实型数)、time(时间型)、realtime(实数时间型);

        (3)event(事件)。

而且,生成的数据类型具有唯一的标识名,也可以被层次引用。生成范围中可以定义使用按照秩序或者参数名赋值的参数重新定义,或者使用defparam声明的参数(需在同一个生成范围内或者生成范围的层次化实例中)重新定义。

        3、任务和函数的声明也允许出现在生成范围之中,但是不允许出现在循环生成中。生成任务和函数同样具有唯一的标识符名称,可以被层次引用

        4、不允许出现在生成范围之中的模块项声明包括:

        (1)参数、局部参数;

        (2)输入、输出和输入/输出声明;

        (3)指定块。

        5、在Verilog中有3中创建生成语句的方法:

        (1)循环生成

        (2)条件生成

        (3)case生成

 

总结

        生成块的主要作用:

        (1)实例引用有条件地调用,即只引用需要用到的实例),可以理解为一种静态展开行为,在仿真开始前,编译器就将代码展开,把行为预先确定下来,不会例化不需要的逻辑分支而生成电路;

        (2)利用标识后唯一的标识名,可以对生成语句中的变量进行层次化引用

 

一、循环生成语句

        (1)关键字:generate-for

        (2)关键字genvar用于声明生成变量(定义for的索引变量),生成变量只能用在生成块中,在确立后的仿真代码中,生成变量是不存在的;

        (3)for循环体的begin后的标识名是赋予循环生成语句的名字,目的在于通过它对循环生成语句中的变量进行层次化引用

//8bit width buffer
module buffer_8(
    input[7:0] din,
    output[7:0] dout
);
    
// Generate block

//声明一个临时循环生成变量,只用于生成块的循环计算
//Verilog仿真时该变量在设计中并不存在
genvar i;
//用一个单循环生成按位取反
generate
	for(i=0; i<8; i=i+1)
		begin:buffer_1_loop	//循环生成语句的标识名
            buffer_1 g1(        //实例引用buffer_1
				.in(din[i]),
				.out(dout[i])
			);
            end		//在生成块内部结束循环
    endgenerate	//结束生成块
	
//根据上面的循环生成,Verilog编译器会自动生成以下相对层次实例名
//buffer_1: buffer_1_loop[0].g1, buffer_1_loop[1].g1,
//          buffer_1_loop[2].g1, buffer_1_loop[3].g1,
//          buffer_1_loop[4].g1, buffer_1_loop[5].g1,
//          buffer_1_loop[6].g1, buffer_1_loop[7].g1。

endmodule
//1bit width buffer_1
module buffer_1(
    input in,
    output out
);

assign out = ~in;

endmodule

 

二、条件生成语句

        (1)关键字:generate-if

        (2) if的条件都为常量条件,根据不同的条件引用不同的实例(这里与普通的if不同,普通的if会例化所有的分支结构生成电路)

 

module ex_generate_if(
	input a, b, c,
	output y
);

//本地参数声明,不能用参数重新定义(defparam)修改
//也不能在实例引用时通过传递参数语句,即#(参数1, 参数2,...)的方法修改
localparam size = 12;

//有条件地调用(实例引用)不同类型的组合逻辑
//根据参数size的值,在调用时引用相对应的组合逻辑实例
generate
	if(size < 8)
		assign y = a & b & c;
	else if(size == 8)
		assign y = a & b | c;
	else
		assign y = a | b | c;	//The generated instance
endgenerate

endmodule

 

三、case生成语句

        (1)关键字:generate-case

        (2)只会选择case的一路分支进行实例例化。

//N位加法器(顶层.v)
module adder(a0,a1,ci,co,sum);

parameter N = 4;

input[N-1:0] a0, a1;
input ci;
output co;
output[N-1:0] sum;

//根据总线的位宽N,调用(实例引用)相应的加法器
//参数N在调用时可以重新定义,调用
generate
	case(N)
		1:			adder_1bit 			adder1(a0,a1,ci,co,sum);
		2:			adder_2bit 			adder2(a0,a1,ci,co,sum);
		default:	adder_cla	#(N)	adder3(a0,a1,ci,co,sum);
	endcase
endgenerate

endmodule

 

你可能感兴趣的:(FPGA)