0

I am trying to make a synthesizable filter in verilog. I have the fixed-point filter coefficients in a text file. I am looking for an elegant and scalable way to pass on these filter coefficients. The filter will not be a simple beast: it will contain multiple sub-modules, and each of which may need a single co-efficient.

Since the filter coefficients will be constant, I would like them to be hardcoded, i.e., not consume any registers in implementation.

I have a few options/wishes below, along with their possible downsides:

  1. Use readmemh or some similar trick to read the coefficients into a memory (reg [15:0] coeff [0:1023]) in the enclosing module, and pass on the coefficients from memory to FIR stages using a generate block. It should look something like:
generate
    for (i = 0; i < 3 ; i = i + 1) begin: k
        filter_stage(input[k], coeff[k], output[k]);
    end
endgenerate

The downside is that the memory must be in the module that encloses the filter stages, otherwise I will have to go through portlist hell.

  1. Use systemverilog packed arrays as module ports. The downside is that systemverilog support for some synthesis tools is sub-optimal.

  2. This is a wish: Some sort of global lookup structure which is accessible to each module, so I don't have to manually wrap modules and adjust portlists just to pass coefficients to the right place.

I would want to know if option 3 is at all possible. If not, what else could I do?

Thanks.

0

2 Answers 2

2

If you are able to use SystemVerilog, then you can put constants (maybe an array of constants) in a package, and import (not include) the package in other modules which need access.
Its been written about a lot, here is a starting point include/import.

SystemVerilog packages are synthesizable, they not just for verification.

I have used them for Vivado RTL work for several years, seems like since Vivado 2016.
This link says packages are supported for Quartus Synthesis in 2012 Altera support for SV

The only place you might have synthesis support issues is with ISE; the last release was 2014. I don't know about Microsemi or the other mid-sized or small FPGA vendors.

You don't need option 1, you don't need ports as mentioned in 2, and you don't have to wrap anything or use ports as mentioned in 3.

An array of constants in a package should work well.

The package syntax is lightweight, you could have Matlab or Python or whatever you use for coefficient generation write out the SystemVerilog package with the constants.

Example package defines an array of constants

// Write me out with Python or Matlab generated coefficients
package my_coef_pk;

// type int is 32 bit, treated as signed
localparam int my_coef_array [4:0] = 
 '{
   2**16,
   1,
   2, 
  -1,
  -(2**16)
  };

endpackage

Example testbench imports the package and prints the array

module tb ();
  // import the contents of the package here
  import my_coef_pk::*;
  
  // example access the localparam array defined in the package
  initial 
    foreach(my_coef_array [i])
      $display("my_coef_array = %d", my_coef_array [i]);
    
endmodule

Produces

my_coef_array =       65536
my_coef_array =           1
my_coef_array =           2
my_coef_array =          -1
my_coef_array =      -65536
Sign up to request clarification or add additional context in comments.

1 Comment

Excellent. Seems promising. I'll look into it.
1

About the global lookup structure: In Verilog simulation, pretty much everything's "global". You can use hierarchical reference to access any variable in any module. But in synthesis, user defined variables are not and cannot be global. Every state variable needs a route to move its value from one place to another.

You have limited choices here and in my understanding, passing the coeff is the simplest way to send values to your filter. Alternatively, you can use array of parameters in your top module and pass those parameters to the bottom module.

Further, you can check this include file method here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.