0

Is there a way to manipulate variable instantiation depending on a parameter?

For example, here if I were to put just bit [WIDTH-1:0] a; and set DEPTH == 1, WIDTH would be 0 and bit [-1:0] a; would not make sense.

When I code it like in the example below I get an error on the second $display: "Undeclared identifier: a". Is there a way to achieve this in Verilog/SV or is there an error in my code?

module test #(
  parameter DEPTH = 2,
  parameter WIDTH = $clog2(DEPTH)
)();

  generate
    if (WIDTH == 0) begin
      bit             a;
    end else begin
      bit [WIDTH-1:0] a;
    end
  endgenerate

  initial begin
    $display("WIDTH: %d", WIDTH);
    $display("Bit width of a: %d", $bits(a));
  end
endmodule: test

3 Answers 3

3

All you need to do is

bit [(WIDTH>0 ? WIDTH-1 : 0):0] a;
Sign up to request clarification or add additional context in comments.

Comments

0

Which version of Verilog are you using? $clog2 was introduced in Verilog-2005. Prior implementations, can give odd results.

See below, I did a loop to show incrementing depth versus result of clog2.

CLOG2(0) =           0
CLOG2(1) =           0
CLOG2(2) =           1
CLOG2(3) =           2
CLOG2(4) =           2

To represent the value of 1, for instance, you need 1 bit, not 0 To represent the value of 2, you need 2 bits...not 1. To represent the value of 4, you need 3 bits. CLOG2 is always 1 short at the transition points. The prior solution will not account for that as you grow.

So if you say

WIDTH = $clog(DEPTH+1);

I think you will automatically get the results you want.

1 Comment

I'm using SystemVerilog. Unfortunately, I want the result of CLOG2(1) and CLOG2(2) to be both 1, so this is not what I need.
0

I made & use this on a regular basis. It determines the width in bits of an integer value. Special case of 0 will return a value of 1 (you still need 1 bit to hold the value). Let's say you need to define an index variable based on memory that has 256 addresses

parameter NUM_ADDR 256

localparam A_SZ = bit_size(NUM_ADDR-1); // example: 255 (highest address) should return 8

logic [A_SZ-1:0] index; // example: [7:0] index

Then All I ever need to change is NUM_ADDR

function integer bit_size;
input integer value;
reg [31:0] shifted;
integer res;
begin
  if (value != 0)
  begin
       shifted = value;
       for (res=0; (shifted != 0); res=res+1)
           shifted = shifted >> 1;
       bit_size = res;
  end
  else
     bit_size = 1; // minimum size, even for a value of 0
end
endfunction

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.