Verilog学习笔记------生成块
生成语句可以动态地生成Verilog代码。可以对矢量中的多个位以及多个模块的实例引用进行重复操作,可以根据参数确定程序中是否包含Verilog某段代码。生成语句可以控制变量的声明、任务和函数的调用、还能对实例引用进行全面的控制。在编程时,应用关键字generate_endgenerate来说明生成的实例范围。
生成实例可以是一下的以下一种或多种类型:
1)模块 ;
2)用户定语原语 ;
3)门级原语 ;
4)连续赋值语句;
5)initial 和 always 块。
生成实例中语序的数据类型:
1)wire型 reg型;
2)integer型,real型,time型,realtime型;
3)event型。
究竟是使用按照次序或者参数名赋值的参数冲定义,还是使用defparam声明的参数重新定义,都可以在生成范围中定义。例
生成的数据、实例、任务、函数都具有唯一的标识名,可以被层次引用。(任务和函数的声明可以出现在生成范围之中,但是不能出现在循环过程当中)
不允许出现在生成范围之中的模块项声明:
1)参数、局部参数;
2)输入、输出、输入/输出声明;
3)指定块。
一、循环生成语句
循环生成语句允许使用者对下面的模块或模块项进行多次的实例引用;
1)变量声明;
2)模块;
3)用户定义原语、门级原语;
4)连续赋值语句;
5)initial 和 always 块。
例、两个N位总线变量进行按位异或
//本模块生成两条N位总线变量的按位异或
module bitwise_xor(out, i0 ,i1);
//参数声明语句,参数可以重新定义
parameter N = 32 ; // 默认的总线位宽为32位
//端口声明语句
output [N-1 : 0] out ;
input [N-1 : 0] i0, i1;
//声明一个临时循环变量
//改变变量只用于生成块的循环计算
//Verilog仿真时该变量在设计中并不存在
genvar j ;
generate
for(j = 0; j < N; j = j + 1)
begin: xor_loop
xor g1(out[j], i0[j],i1[j]) ;
end //在生成块内部结束循环
endgenerate //结束生成快
//另一种编写形式
//异或门可以用always块来替代
//reg [N-1 : 0] out ;
//generate
// for(j = 0; j < N; j = j+1)
// begin : bit
// always @ (i0[j] or i1[j])
// out[j] = i0[j] ^ i0[j] ;
// end
//endgenerate
endmoudle
1.生成块的本质是使用循环内的一条语句来替代多条重复的Verilog语句,简化用户的编程。
2.关键词genvar用于声明生成变量,生成变量只能用在生成块之中;在明确后的仿真代码中,生成变量是不存在的。
3.一个生成变量的值只能由循环生成语句来改变。
4.循环生成语句可以嵌套使用,不过使用同一个生成变量作为索引的循环生成语句不能够相互嵌套。
5.xor_loop是赋值循环生成语句的名字,目的在于通过它对循环生成语句之中的变量进行层次化引用。
二、条件生成语句
条件生成语句类似于 if_else_if 的生成构造,该结构可以在设计模块中根据经过仔细推敲并确定表达式,有条件的调用以下结构:
1)模块;
2)用于定义的原语,门级原语;
3)连续赋值语句;
4)initial 或always 块。
//本模块实现一个参数化乘法器
moudle multiplier(product, a0, a1);
//参数声明,该参数可以重新定义
parameter a0_width = 8 ;
parameter a1_width = 8 ;
//本地参数声明
//本地参数不能用参数重定义修改
//也不能在实例引用时通过传递参数语句,即 (参数1, 参数2,...)的方法修改
localparam product_width = a0_width + a1_width ;
//端口声明语句
output [porduct_with-1 : 0] product ;
input [porduct_with-1 : 0] a0 ;
input [porduct_with-1 : 0] a1 ;
//有条件地调用(实例引用)不同类型的乘法器
//根据参数 a0_width 和 a1_width的值,在调用时引用相对应的乘法器实例
generate
if((a0_width < 8) || (a1_width < 8))
cal_multiplier #(a0_width, a1_width) m0(product, a0, a1) ;
else
tree_multiplier #(a0_width, a1_width) m0(product, a0, a1) ;
endgenerate //生成块的结束
endmoudle
三、case生成语句
case生成语句可以调用以下的结构:
1)模块;
2)用于定义的原语,门级原语;
3)连续赋值语句;
4)initial 或 always块。
//本模块生成N位的加法器
moudle adder(co, sum, a0, a1, ci);
//参数声明,本参数可以重新定义
parameter N = 4 ; //缺省的总线位宽为4
//端口声明
output [N-1 : 0] sum ;
output co ;
input [N-1 : 0] a0 ,a1 ;
input ci ;
//根据总线的位宽,调用(实例引用)相应的加法器
//参数N在调用(实例引用)时可以重新定义,调用(实例引用)
//不同位宽的加法器是根据不同的N来决定的
generate
case(N)
//当N=1或N=2时分别选用位宽为1位或2位的加法器
1: adder_1bit adder1 (co, sum, a0, a1, ci) ; //1位的加法器
2: adder_2bit adder2 (co, sum, a0, a1, ci) ; //2位的加法器
//默认的情况下选用位宽为N位的超前进位加法器
default :adder_cla #(N) adder3 (co, sum, a0, a1, ci) ;
endcase
endgenerate //生成块的结束
endmoudle