verilog generate的使用

之前一直在排斥对generate的使用,认为这种类似于c语言中for的循环语法并不适用于FPGA设计,因为FPGA实际上还是硬件,循环N次,就会映射N个同样的模块到FPGA,也就是多消耗的N倍的资源,为了节约资源多都会选择复用的方式来处理类循环数据。

但是殊不知在处理循环数据的时候还是会消耗一定的资源以及逻辑调试的时间成本(同时也可能买下bug),最终可能也节约不了多少资源,而且相比于处理逻辑,循环语句要简洁明了,便于代码的阅读和维护。

随着工艺水平的提升,资源貌似也并不是项目考虑的首要因素了,大家都会留出充足的余量,所以开始正视这种generate“非主流”verilog语法。

Verilog-2001中新增了语句generate,通过generate循环,可以产生一个对象(比如一个元件或者是一个模块)的多次例化,为可变尺度的设计提供了方便,generate语句一般在循环和条件语句中使用,为此,Verilog-2001增加了四个关键字generate,endgenerate, genvar, localparam,genvar是一个新增的数据类型,用在generate的循环中的标尺变量必须定义为genvar类型。

generate语句的最主要功能就是对module、reg、assign、always、task等语句或者模块进行复制。

generate语句有generate_for、generate_if、generate_case三种语句。

一、generate for

note:

1、generate for语句必须有genvar关键字定义for的变量,不可以是reg型,integer型

2、for 的内容必须加begin和end

3、一般要给for语段起个名字(BLOCK1)

// Generate block
genvar i;
generate
    for(i=0; i<8; i=i+1) begin:BLOCK1
        buffer_1 buffer_1_1(.in(din[i]), .out(dout[i]));
    end
endgenerate

二、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

三、generate case

generate_case其实跟generate_if一样,都是根据参数(都必须为常量)作为判断条件,来产生满足条件的电路,不同于使用了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

 

 

### Veriloggenerate语句的使用方法 #### generate语句概述 在FPGA程序开发过程中,遇到多个相似代码使用或者对多个模块调用的情况时,`generate`语句能够简代码并提高可读性和维护性。该语句允许动态创建多个结构代码块,从而避免重复编写类似的逻辑[^1]。 #### genvar变量的作用 为了实现循环生成实的功能,在`generate`块内部定义了一种特殊的整型变量——`genvar`。这种类型的变量主要用于控制循环次数以及索引位置等参数设置,它只可以在`generate`范围内声明和应用[^2]。 #### Generate语句的具体形式 ##### 1. `generate-for` 循环 通过指定起始值、终止条件及增量表达式来构建一系列相同或略有差异的设计单元。下面是一个简单的子展示了如何利用for循环生成N个加法器: ```verilog module adder_gen #(parameter N=8)(input [7:0] a,b,output reg [7:0] sum); genvar i; generate for(i=0;i<N;i=i+1) begin : ADDER_GEN assign sum[i]=a[i]^b[i]; // 这里仅做异或操作作为示范 end endgenerate endmodule ``` ##### 2. `generate-if` 条件判断 当需要根据不同情况有条件地生成某些部分电路时,则可以采用if分支来进行选择性的实处理。如根据配置选项决定是否加入额外功能模块: ```verilog module config_based_module(input clk, input rst_n, output wire out); parameter USE_EXTRA_FEATURE = 1'b1; genvar j; generate if (USE_EXTRA_FEATURE == 1'b1) begin : WITH_FEATURE always @(posedge clk or negedge rst_n) if (!rst_n) out <= 1'b0; else out <= ~out; // 反相输出 end else begin : WITHOUT_FEATURE assign out = 1'bx; // 默认高阻态 end endgenerate endmodule ``` ##### 3. `generate-case` 多路选择 对于更复杂的场景下可能涉及到多条路径的选择问题,此时case语句就显得尤为重要了。它可以基于某个信号的不同取值范围分别执行相应的动作,如下所示为一个三选一MUX的子: ```verilog module mux_3to1 #(parameter WIDTH=4)( input [WIDTH-1:0] d0,d1,d2, input [1:0] sel, output reg [WIDTH-1:0] q); genvar k; generate case(sel) 2'b00:begin:MUX_SEL0 always @(*) q=d0; end 2'b01:begin:MUX_SEL1 always @(*) q=d1; end default:begin:MUX_DEFAULT always @(*) q=d2; end endcase endgenerate endmodule ``` 以上就是关于Verilog中的`generate`语句的主要介绍及其具体的应用方式[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

superyan0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值