Search code examples
constantsverilogsystem-verilog

Store constants in a file, use for module Instantiation in generate block


I am currently trying to implement an fir-filter consisting of N taps. I have written the code for a single tap and want to generate N single taps in the top module.

module fir #(
  parameter DataWidthBits = 32,
  parameter N = 3
)(
  ....
);
  genvar gen_i;
  generate
    for (gen_i=0; gen_i<N; gen_i=(gen_i+1)) begin : single_taps
      fir_one_tap #(DataWidthBits, filter_coeffs[i]) fir_one_tap_inst (i_clk, i_resetn, r_sample_delay[gen_i], r_adder[gen_i]);
    end
  endgenerate

Each of the taps can be parametrized with DataWidth and a coefficient from filter_coeffs. My idea was to read these values from a .csv-file consisting of hex-values like the following

0, 1, A

This is how I tried reading the file and save the hex values to a localparam array:

localparam [DataWidthBits-1:0] filter_coeffs [FilterTaps-1:0];
initial begin
    integer coeff_file, scan_ret;
    coeff_file = $fopen("coeffs_hex.csv", "r");
    while (i < FilterTaps) begin
      scan_ret  = $fscanf(coeff_file, "%h", filter_coeffs[i]);
    end
    $fclose(coeff_file);
end

While linting, I receive the following error:

Parameter without initial value is never given value (IEEE 1800-2017 6.20.1): 'filter_coeffs'
                       : ... note: In instance 'fir_wbs.fir'
   57 |     localparam [DataWidthBits-1:0] [FilterTaps-1:0] filter_coeffs;

I suspected that I did write values from the csv file into the filter_coeffs array and therefore gave them a value.


Solution

  • Your syntax is illegal. You must assign constant values to a locapram when you declare it, for example:

    localparam WIDTH = 5;
    

    Constants, like localparam, must be assigned before simulation begins. This means they can not be assigned in procedural code (like an initial block).

    Refer to IEEE Std 1800-2017, section 6.20 Constants.


    The standard way to set parameters via an external file is with a `include file. But, you have the same issue: the include file must contain legal syntax.

    You can always use your favorite software language to automatically generate any Verilog code you need and include it with your compiled Verilog files.


    If Python is used to create coefficients, consider firwin or firwin2 from the package scipy.signal.