SystemVerilog: derive input width from parameter

2.5k views Asked by At

I have an input whose width I want to determine at elaboration time. Instead of feeding two parameters I want to determine the width derived from a single parameter. Something like this:

module my_module #(
  COUNT = 9
) (
  [bitwidth(COUNT)-1:0] index
);

I have a function which works for me if I declare a reg internal to my module but I need this to be driven externally via the port map.

function integer bitwidth;
  input integer n;
  integer exp2, width;
begin
  width=1;
  for (exp2=1; exp2<<1 <= n; exp2=exp2<<1)
    width=width+1;
  bitwidth = width;
end
endfunction

reg [bitwidth(COUNT)-1:0] this_works = COUNT;

How do I accomplish this? Can I utilize an interface (+modports) to get me what I want?

1

There are 1 answers

0
dave_59 On

It would really help to show a complete self contained example. The following worked for me

module my_module #(
  COUNT = 9
) (
  [bitwidth(COUNT)-1:0] index
);
function integer bitwidth;
  input integer n;
  integer exp2, width;
begin
  width=1;
  for (exp2=1; exp2<<1 <= n; exp2=exp2<<1)
    width=width+1;
  bitwidth = width;
end
endfunction
   initial $displayb(index);
endmodule
module top;
   my_module #(10) mm();
endmodule

A couple of comments about this code if we were to assume that $clog2 didn't exist.

  • Never rely on implicit port directions and types, be explicit for clarity and show intent.
  • Use ANSI style argument lists.
  • Use int instead of integer.

module my_module #( COUNT = 9 ) ( input wire [bitwidth(COUNT)-1:0] index ); function integer bitwidth(input int n); int width; width=1; for (int exp2=1; exp2<<1 <= n; exp2=exp2<<1) width=width+1; bitwidth = width; endfunction initial $displayb(index); endmodule module top; my_module #(10) mm(); endmodule