Monday, 2 January 2017

How to use Parameters in SystemVerilog

In this blog, we will see how to set and overwrite the parameters in the testbench. As we know, whenever changes required in define, we have to compile the code before simulate it. But in case of parameters, we can directly pass its value through simulation time argument and we don't need to compile the code again.


Consider case of AMBA protocols where you may need to have different address/data width and also need to generate data based on the width of the signal. So here, we can use parameter to generate different values.


For overwriting the parameter field, user has to pass “+floatparameters” during optimization [with vopt command]. If the design is not optimized then similar command could be passed with simulation time [with vsim command]. The parameter field should be passed during simulation time with “-g” prefix.

Below is a demo example which has a parameter “DATA_WIDTH” which defines the width of signals. 

Below is the example for usage of parameter with Questa-Sim.


Example:
module adder(in1, in2, en, clk, out);
  parameter DATA_WIDTH=4;
  output [DATA_WIDTH : 0] out;
  input [(DATA_WIDTH-1):0] in1;
  input [(DATA_WIDTH-1):0] in2;
  input en;
  input clk;

  reg [DATA_WIDTH:0] r_out;

  assign out = r_out;

  always @(posedge clk)
  begin
    if (en) begin
      r_out <= in1 + in2;
    end
  end
endmodule

module testbench();
  parameter DATA_WIDTH=2;
  wire  [DATA_WIDTH : 0]  out;
  wire [(DATA_WIDTH-1):0] in1;
  wire [(DATA_WIDTH-1):0] in2;
  wire en;
  wire clk;

  reg [(DATA_WIDTH-1):0] r_in1;
  reg [(DATA_WIDTH-1):0] r_in2;
  reg r_en;
  reg r_clk;

  assign clk = r_clk;
  assign en  = r_en;
  assign in1 = r_in1;
  assign in2 = r_in2;

  initial begin
    r_clk <= 0;
    $monitor(in1, in2, out);
    forever begin
      #5 r_clk = ~r_clk;
    end
  end

  initial begin
    r_en <= 0;
    r_in1 <= 0;
    r_in2 <= 0;

    #5 r_en = 1;
    #10 r_in1 = $urandom_range(128,0);
          r_in2 = $urandom_range(128,0);
    #10 r_in1 = $urandom_range(128,0);
           r_in2 = $urandom_range(128,0);
    $finish;
  end
  
  adder#(DATA_WIDTH) add(in1, in2, en, clk, out);

endmodule



Compile command: vlog file.sv


The following command should be used to simulate above example:
vsim -novopt -do "log -r *;run -a" testbench -voptargs="+floatparameters" -gDATA_WIDTH=6 –c


So, it will take "DATA_WIDTH" value "6" in the entire testbench. User can pass different values of "DATA_WIDTH" with "-g" option. If this parameter is not passed during simulation time, then "DATA_WIDTH" value will be "2" which is set as default in the testbench.



Note that, by this method, the parameters defined in the packages will not be overridden. So that, the testbench component can not use this overriden value.