Verilog Generate可以实现批量的信号定义与赋值、模块例化

对于相关器(Correlator)电路,它对两个输入信号在一定窗口范围内进行乘积,然后对积进行叠加作为输出。如果需要低延时的相关器输出,就需要将每一个采样值作为被乘数(根据实际需要的过采样率来决定抽头个数)。一般这样的相关器会消耗更多的资源。

相关器实现的结构如图:

要实现这样的相关器,一种可行的做法是用MATLAB/C程序,产生期望的大量的格式化代码保存在.v文件,然后用`include把这段代码放到需要的地方(比如wire声明,reg声明,assign赋值,always里面<=赋值)。注意在工程中,将这些.v文件作为头文件而不是设计文件来管理(否则编译器认为语法出错)。这样做的缺点是:每一段代码需要用一个.v文件保存,而且每次进行代码修改都需要运行MATLAB/C程序。

Verilog有generate结构可以实现上述的“代码堆叠”操作。

上面的结构图中有3个地方可以generate:1、d1信号的采样移位。2、d2信号的采样移位。3、乘法器组。

模块的关键参数:1、N=30,为移位寄存器的阶数。2、每一级移位寄存器是5-bit Signed乘法器。3、din_shift_reg是二位数组的定义形式,即reg signed[4:0] din_shift_reg[29:0]。

给出移位寄存器的generate实现:

//***    Shift Operation
genvar ite_din;
generate
    for(ite_din=0; ite_din<N; ite_din=ite_din+1)begin: din_op  // 记得for结构需要用begin开头,并且为generate结构加标识符,如din_op
        always@(posedge ts_sam_clk)begin
            if(!rst_n)begin
                din_shift_reg[ite_din] <= 5'd0;
            end
            else begin
                if((N-1) == ite_din)begin
                    din_shift_reg[ite_din] <= din;  // New Data In-Buff
                end
                else begin
                    din_shift_reg[ite_din] <= din_shift_reg[ite_din+1];  // Shift Operation
                end
            end
        end
    end  // 记得for结构需要end结尾
endgenerate

给出乘法器的generate实现:

//***    Generate Multiplier
genvar ite_mult;
generate
    for(ite_mult=0; ite_mult<N; ite_mult=ite_mult+1)begin: mult_op
        mult_s5 mult_s5_inst(
        .clock(ts_sam_clk),
        .dataa(din_shift_reg[ite_mult]),
        .datab(local_reg[ite_mult]),
        .result(prod[ite_mult])
        );
    end
endgenerate

说明和一些理解:generate结构将其内部的结构例化/生成多次,各个结构的参数可以通过genvar进行配置。

等效的结构图:

posted @ 2020-04-21 18:08  ygpygp1234  阅读(6888)  评论(2编辑  收藏  举报