目录
1.generate for
2. generate if
3. generate case
条件编译在图像处理领域非常有用,特别是图像处理的算法处理方面。由于资源限制,处理尺寸不可能像软件那样到运行时调整,但是有时候需要对不同尺寸进行测试,或者算法需要两个尺寸的算子进行配合。这个时候为两个尺寸算子设计两套独立的电路是非常麻烦的事情。用Verilog中的 generate语句 就可以实现条件编译的功能了,这个功能就类似于C语言中的#ifdef语句。
Verilog-2001标准中添加了generate循环,其主要的功能就是允许产生module和primitive的多个例化,同时也可以产生多个variable,net,task,function , continous assignment ,initial和always。在generate语句中可以引入if-else和case语句,根据不同条件产生不同的例化。
用法:
使用Generate for时候必须要注意以下几点要求:
ex1:一个简单的例子就是二维卷积过程中,根据不同的处理尺寸例化不同数据的行缓存,实例如下:
ex2:例化 module
ex3: 进行多个assign赋值
generate for(i=0; i<4; i=i+1)
begin : gfor_block
assign temp[i] = indata[2*i+1:2*i];
end
等同于:
assign temp[0] = indata[1:0];
assign temp[1] = indata[3:2];
assign temp[2] = indata[5:4];
assign temp[3] = indata[7:6];
ex4.利用generate for赋值 always
generate for(i=0; i<4; i=i+1)
begin : gfor_block
always @ (*)
temp[i] = indata[2*i+1:2*i];
end
endgenerate
等同于:
always @ (*)
temp[0] = indata[1:0];
always @ (*)
temp[1] = indata[3:2];
always @ (*)
temp[2] = indata[5:4];
always @ (*)
temp[3] = indata[7:6];
generate用来复制模块,而在电路设计中,对于不同的参数,其电路细节也不同:generte if语句就是根据模块的参数(必须是常量)作为判断条件进行判断,来产生满足条件的电路。
ex1:
generate
if(KSiZE == 3)
begin: MAP16
//针对尺寸为3的算法进行处理
end
end generate
generate
if(Ksize == 5)
begin
//针对尺寸为5的算法进行处理
end
ex2:
module assign_test(ia,ib,ic,od)
input ia,ib,ic;
ouput od;
laocalparam WIDE = 8;//参数模块,用于选择生产的电路
generate
if(WIDE < 10)
assign d = a | b | c;
else
assign d = a & b & C;
generatate
endmodule
RTL电路如下:
如果将参数 WIDE改为12则综合后的电路为:
generate case其实跟generate if 一样,都是会根据模块的参数(要求是常量)来综合出满足条件的电路。
module case_test(ia,ic,ic,od);
input ia, ib , ic;
output od;
localparam WIDE =3 ;//
generate
case (WIDE)
9:
assign d = a | b | c;
12: assgin d = a & b & c;
default: assgin d = a & b | c;
endcase
endgenerate
endmodule
将WIDE改为9后RLT:
补充:
在Verilog-1995中可以选择向量即mem的任一位输出,也可以选择向量的连续几位输出,不过此时连续几位的始末数值的index需要是常量,即mem[5:3]。而在verilog-2001中可以用变量作为index,进行part select。
this is the so-called “Indexed vector part selects”
[base_expr+:width_expr] //positive offset
[base_expr-:width_expr] //negative offset
其中base_expr可以是变量,但是width_expr必须是常量。
+:表示由base_expr向上增长width_expr位;
-:表示由base_expr向上递减width_expr位。
ex
reg [63:0] word;
reg [3:0] byte_num; //a value from 0 to 7
wire [7:0] byteN = word [byte_num*8+:8] ;
如果byte_num值为4时,则将word[39:32]赋值给byteN。
参考资料:《基于FPGA的数字图像处理及应用》
《Verilog数字系统设计教程》