2

I want to create and define a localparam array in SystemVerilog. The size of the array should be configurable, and the value of each localparam array cell calculated based on its location. Essentially this code:

localparam [7:0] [ADDR_BITS-1:0] ADDR_OFFSET = '{
  7*PAGE_SIZE,
  6*PAGE_SIZE,
  5*PAGE_SIZE,
  4*PAGE_SIZE,
  3*PAGE_SIZE,
  2*PAGE_SIZE,
  1*PAGE_SIZE,
  0
};

but where the first '7' is replaced with a parameter, and where the parameter initialization is extended to the generic case. So I need a way to loop from 0 to (N-1) and set ADDR_OFFSET(loop) = loop*PAGE_SIZE.

The "obvious" option in SystemVerilog would be generate, but I read that placing a parameter definition inside a generate block generates a new local parameter relative to the hierarchical scope within the generate block (source).

Any suggestions?

For background reference: I need to calculate an actual address based on a base address and a number. The calculation is simple: real_address = base_address + number*PAGE_SIZE

However, I don't want to have the "*" in my code since I am afraid the synt tool will generate a multiplier, that it will then try to simplify since PAGE_SIZE is a constant value. I am guessing that this can lead to more logic than if I try to do all calculations when generating the localparam array, since this for sure will not give any multiplier in logic.

So with the above localparam definition, I perform the desired address calculation like this:

  function [ADDR_BITS-1:0] addr_calc;
    input [ADDR_BITS-1:0] base_addr;
    input [NBITS-1:0]  num;

    addr_calc = base_addr + ADDR_OFFSET[num];
  endfunction

I think perhaps I found a solution. Wouldn't I essentially accomplish the same by not defining a localparam array, but rather performing the address calculation inside a loop? Since systemverilog sees the loop variable as "constant" (when it comes to generating logic) that seems to accomplish the same? Like this (inside the function I wrote above):

for (int loop1 = 0; loop1 < MAXNUM ; loop1++) begin
  if (num == loop1) begin
    addr_offset = CSP_PAGE_SIZE*loop1;
  end
  addr_calc = base_addr + addr_offset;
end

1 Answer 1

7

You can set your localparam with the return value of a function.

   localparam bit [7:0] [ADDR_BITS-1:0] ADDR_OFFSET = ADDR_CALC();
   function bit [7:0] [ADDR_BITS-1:0] ADDR_CALC();
      for(int ii=0;ii<$size(ADDR_CALC,1); ii++)
    ADDR_CALC[ii] = ii * PAGE_SIZE;
   endfunction 
Sign up to request clarification or add additional context in comments.

1 Comment

Does anybody know which synthesis tools support this? Given that this is more of a "generate" construct to initialize an array, I would think this particular use of parametrized function is OK with synthesis? In general, parametrized functions for actual logic need to be static within a virtual class.

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.