SystemVerilog Parametrized Module

Here’s the one and only code example you need for reference. It shows

  • How you can parametrize a SystemVerilog module
  • How one input parameter can depend on another
  • How to instantiate such a module
module module_parameter
#(parameter
    MEM_WD=8,
    MEM_DEPTH=16,
    MEM_ADDR=$clog2(MEM_DEPTH))
(
    input  logic                clk,
    input  logic                rst,
    input  logic                rd,
    input  logic                wr,
    input  logic [MEM_ADDR-1:0] addr,
    input  logic [MEM_WD-1:0]   wr_data,
    output logic [MEM_WD-1:0]   rd_data
); 

    logic [MEM_DEPTH-1:0][MEM_WD-1:0] tbl;
    ...
endmodule: module_parameter

Following snippet shows how the parametrized can be instantiated. Notice how I’ve skipped .MEM_ADDR parameter. It has been assigned the default value of $clog2(MEM_WD)

module tb_top;
    logic        clk, rst, rd, wr;
    logic [4:0]  addr;
    logic [15:0] wr_data;
    logic [15:0] rd_data;

    // This is how you instantiate the
    // parametrized module
    module_parameter #(
        .MEM_WD(16),
        .MEM_DEPTH(32)
    ) dut (
        .*
    );

endmodule:tb_top

If you have other unique examples of how paramterized modules can be use, share them in the comments below.

1 Like

I think it would a good idea to make MEM_ADDR as a localparam instead. That way, the user of the module can never overwrite its value.