Verilog defparam

Verilog defparam

文章目录

一、背景

当一个模块被另一个模块引用例化时,高层模块可以对低层模块的参数值进行改写。这样就允许在编译时将不同的参数传递给多个相同名字的模块,而不用单独为只有参数不同的多个模块再新建文件。

参数覆盖有 2 种方式:1)使用关键字 defparam,2)带参数值模块例化。

二、模块例化传参与defparam的对比

2.1 带参数模块例化的例子

c 复制代码
//instantiation
ram_4x4 #(.MASK(7))
    u_ram_4x4
    (
        .CLK    (clk),
        .A      (a[4-1:0]),
        .D      (d),
        .EN     (en),
        .WR     (wr),    //1 for write and 0 for read
        .Q      (q)    );

2.2 defparam的例子

c 复制代码
//instantiation
defparam     u_ram_4x4.MASK = 7 ;
ram_4x4    u_ram_4x4
    (
        .CLK    (clk),
        .A      (a[4-1:0]),
        .D      (d),
        .EN     (en),
        .WR     (wr),    //1 for write and 0 for read
        .Q      (q)    );

(1)建议,对已有模块进行例化并将其相关参数进行改写时,不要采用 defparam 的方法。除了上述缺点外,defparam 一般也不可综合。

(2)建议,模块在编写时,如果预知将被例化且有需要改写的参数,都将这些参数写入到模块端口声明之前的地方(用关键字井号 # 表示)。这样的代码格式不仅有很好的可读性,而且方便调试。

三、defparam

可以用关键字 defparam 通过模块层次调用的方法,来改写低层次模块的参数值。

3.1 例子

要传一个值到ram模块中去。对一个单口地址线和数据线都是 4bit 宽度的 ram 模块的 MASK 参数进行改写:

c 复制代码
module  ram_4x4
    (
     input               CLK ,
     input [4-1:0]       A ,
     input [4-1:0]       D ,
     input               EN ,
     input               WR ,    //1 for write and 0 for read
     output reg [4-1:0]  Q    );
 
    parameter        MASK = 3 ;
 
    reg [4-1:0]     mem [0:(1<<4)-1] ;
    always @(posedge CLK) begin
        if (EN && WR) begin
            mem[A]  <= D & MASK;
        end
        else if (EN && !WR) begin
            Q       <= mem[A] & MASK;
        end
    end
 
endmodule

testbench 编写如下:

c 复制代码
`timescale 1ns/1ns
 
module test ;
    parameter    AW = 4 ;
    parameter    DW = 4 ;
 
    reg                  clk ;
    reg [AW:0]           a ;
    reg [DW-1:0]         d ;
    reg                  en ;
    reg                  wr ;
    wire [DW-1:0]        q ;
 
    //clock generating
    always begin
        #15 ;     clk = 0 ;
        #15 ;     clk = 1 ;
    end
 
    initial begin
        a         = 10 ;
        d         = 2 ;
        en        = 'b0 ;
        wr        = 'b0 ;
        repeat(10) begin
            @(negedge clk) ;
            en     = 1'b1;
            a      = a + 1 ;
            wr     = 1'b1 ;  //write command
            d      = d + 1 ;
        end
        a         = 10 ;
        repeat(10) begin
            @(negedge clk) ;
            a      = a + 1 ;
            wr     = 1'b0 ;  //read command
        end
    end // initial begin
 
    //instantiation
    defparam     u_ram_4x4.MASK = 7 ;
    ram_4x4    u_ram_4x4
    (
        .CLK    (clk),
        .A      (a[AW-1:0]),
        .D      (d),
        .EN     (en),
        .WR     (wr),    //1 for write and 0 for read
        .Q      (q)
     );
 
    //stop simulation
    initial begin
        forever begin
            #100;
            if ($time >= 1000)  $finish ;
        end
    end
 
endmodule // test

仿真结果如下:

图中黄色部分,当地址第一次为 c 时写入数据 4, 当第二次地址为 c 时读出数据为 4;可知此时 ram 行为正确,且 MASK 不为 3。 因为 ram 的 Q 端 bit2 没有被屏蔽。

当第一次地址为 1 时写入数据为 9,第二次地址为 1 时读出的数据却是 1,因为此时 MASK 为 7,ram 的 Q 端信号 bit3 被屏蔽。由此可知,MASK 参数被正确改写。

相关推荐
日晨难再5 天前
Verilog基础:$display系统函数和C语言中的库函数printf的区别
c语言·硬件工程·verilog·数字ic
日晨难再9 天前
Verilog基础:时序调度中的竞争(四)(描述时序逻辑时使用非阻塞赋值)
fpga开发·硬件工程·verilog·fpga·数字ic
FPGA狂飙11 天前
FPGA IP 和 开源 HDL 一般去哪找?
fpga开发·verilog·fpga·vivado·xilinx
小桶qa13 天前
握手传输 & 状态机序列检测(记忆科技笔试题)_2024年9月2日
verilog
看未来捏18 天前
【数字集成电路与系统设计】Chisel/Scala简介与Verilog介绍
scala·verilog·chisel
小桶qa19 天前
音频左右声道数据传输_2024年9月6日
音频·verilog
吉孟雷21 天前
ZYNQ FPGA自学笔记
fpga开发·verilog·led·仿真·vivado·zynq
热爱学习地派大星1 个月前
BRAM IP Native模式使用
fpga开发·ip·verilog·fpga·存储器·bram
FPGA狂飙1 个月前
1分钟 快速掌握 双向信号(inout信号)
fpga开发·verilog·fpga·xilinx
米联客(milianke)1 个月前
[米联客-XILINX-H3_CZ08_7100] FPGA程序设计基础实验连载-24 TPG图像测试数据发生器设计
fpga开发·verilog