generate为verilog中的生成语句,当对矢量中的多个位进行重复操作时,或者当进行多个模块的实例引用的重复操作时,或者根据参数的定义来确定程序中是否应该包含某段Verilog代码的时候,使用生成语句能大大简化程序的编写过程。
Verilog-2001添加了generate循环,允许产生module和primitive的多个实例化,generate语句的最主要功能就是对module、reg、assign、always、task等语句或者模块进行复制。
在generate语句中可以引入if-else和case语句,根据条件不同产生不同的实例化。
在设计中,很多情况下需要编写很多结构相同但是参数不同的赋值语句或者逻辑语句,如果在参数量很大的的情况下,原本的列举就会显得心有余而力不足。c语言中常用for语句来解决此类问题,verilog则为我们提供了generate语句。
一 、用法
1. generate语句有generate_for、generate_if、generate_case三种语句。
2. generate for语句必须有genvar关键字定义for的变量
3. for 的内容必须加begin和end
4. 必须给for语段起个名字
二、生成语句生成的实例范围
关键字generate-endgenerate用来指定该范围。生成实例可以是以下的一个或多个类型:
(1)模块;(2)用户定义原语;(3)门级语句;(4)连续赋值语句;(5)initial和always块。
三、三种语句的区别
3.1 generate-for语句
(1) 必须有genvar关键字定义for语句的变量。
(2)for语句的内容必须加begin和end(即使就一句)。
(3)for语句必须有个名字。
例1:利用generate_for来复制assign语句
module test(bin,gray); parameter SIZE=8; output [SIZE-1:0] bin; input [SIZE-1:0] gray; genvar i; //genvar i;也可以定义到generate语句里面 generate for(i=0;i<SIZE;i=i+1) begin:bit assign bin[i]=^gray[SIZE-1:i]; end endgenerate endmodule
讯享网
等同于下面语句
讯享网module test(bin,gray); parameter SIZE=8; output [SIZE-1:0] bin; input [SIZE-1:0] gray; 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]; endmodule
例2:利用generate_for来复制时序赋值语句
generate genvar i; for(i=0;i<SIZE;i=i+1) begin:shifter always@(posedge clk) shifter[i]<=(i==0)?din:shifter[i-1]; end endgenerate
相当于
讯享网always@(posedge clk) begin shifter[0]<=din; shifter[1]<=shifter[0]; shifter[2]<=shifter[1]; ... ... shifter[SIZE]<=shifter[SIZE-1]; end
3.2 generate-if语句
例子:generate_for用于复制模块,而generate_if则是根据模块的参数(必须是常量)作为条件判断,来产生满足条件的电路。相当于判断语句。
module generate_if( input t0, input t1, input t2, output d ); localparam S = 6; //定义模块所需参数,用于判断产生电路 generate if(S < 7) assign d = t0 | t1 | t2; else assign d = t0 & t1 & t2; endgenerate endmodule
3、generate_case语句
讯享网module generate_case( input t0, input t1, input t2, output d ); localparam S = 8; //定义模块所需参数,用于判断产生电路 generate case(S) 0: assign d = t0 | t1 | t2; 1: assign d = t0 & t1 & t2; default: assign d = t0 & t1 | t2; endcase endgenerate endmodule
四、总结
之前一直在排斥对generate的使用,认为这种类似于c语言中for的循环语法并不适用于FPGA设计,因为FPGA实际上还是硬件,循环N次,就会映射N个同样的模块到FPGA,也就是多消耗的N倍的资源,为了节约资源,经常选择复用的方式来处理类循环数据。
但是殊不知在处理循环数据的时候,还是会消耗一定的资源以及逻辑调试的时间成本,最终可能也节约不了多少资源,而且相比于处理逻辑,循环语句要简洁明了,便于代码的阅读和维护。
随着工艺水平的提升,资源貌似也并不是项目考虑的首要因素了,大家都会留出充足的余量,所以开始正视这种generate“非主流”verilog语法。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/74874.html