TRoa
TRoa

Reputation: 354

Number of bits for a particular count of integer in Verilog

Please see my Verilog test bench code below. Actually I wanted to replace all if-else statements with one or two expressions. Code like this look very loose and dirty. Can somebody tell how may I make this code little more compact. Please note that variables 'i' and 'len' are under focus.

module xyz();

......
....some parts and variable declarations;
......


initial begin
for(i = 1; i <= 65535; i = i+1) begin
    if        (i <= 1)               len = 1;
    else if   (i>1 & i <= 3)         len = 2;
    else if   (i>3 & i <= 7)         len = 3;
    else if   (i>7 & i <= 15)        len = 4;
    else if   (i>15 & i <= 31)       len = 5;
    else if   (i>31 & i <= 63)       len = 6;
    else if   (i>63 & i <= 127)      len = 7;
    else if   (i>127 & i <= 255)     len = 8;
    else if   (i>255 & i <= 511)     len = 9;
    else if   (i>511 & i <= 1023)    len = 10;
    else if   (i>1023 & i <= 2047)   len = 11;
    else if   (i>2047 & i <= 4095)   len = 12;
    else if   (i>4095 & i <= 8191)   len = 13;
    else if   (i>8191 & i <= 16383)  len = 14;
    else if   (i>16383 & i <= 32767) len = 15;
    else if   (i>32767 & i <= 65535) len = 16;

    // This is a task(integer, integer, integer, vector)
    universal_test_task(len, 1, i, 16'hFFFF); 
    end
end
endmodule

The main objective of the code is to control the number of bits for a particular count.

Upvotes: 1

Views: 5675

Answers (3)

Harshavardhan Avula
Harshavardhan Avula

Reputation: 11

In Verilog you can make use of Ternary Operator to achieve the functionality.

module test(i,len);
 input wire [16:0] i;
 output reg [16:0] len;
  
 initial 
     begin
       len = i> 32767 ? 16 :
             i> 16383 ? 15 :         
             i> 8191  ? 14 :
             i> 4095  ? 13 :
             i> 2047  ? 12 :         
             i> 1023  ? 11 :
             i> 511   ? 10 :
             i> 255   ? 9 :         
             i> 127   ? 8 :
             i> 63    ? 7 :
             i> 31    ? 6 :         
             i> 15    ? 5 :
             i> 7     ? 4 :
             i> 3     ? 3 :         
             i> 1     ? 2 : 1 ;
       
       $display(i,,,,,len);
     end
endmodule

In System Verilog $clog2() will help you in doing this

module test;
 
 bit [16:0] i;
 bit [5:0] b;
 bit [16:0] len;
      
 
      
 initial
  begin
    repeat(5)
      begin
        assert(std::randomize(i,b) with { b inside {[1:15]};
                                          i == 2**b; });
        len = $clog2(i)+1;
        $display(i,,,,,len);
      end
  end
  
endmodule

Upvotes: 1

Oldfart
Oldfart

Reputation: 6259

Verilog and System Verilog have a built-in system function $clog2(), i.e., ceiling-of-log2.

It can be shown that the number of digits in base b of a positive integer k is .

In your case you could replace all the if-else statements with single line:

len = $clog2(i+1)

Likewise, $clog2 it is supported by all major synthesis tools as long as you give it a value which is constant during compile-time.

Upvotes: 4

Matthew
Matthew

Reputation: 13967

This sounds like a job for a recursive log2 function:

  function int log2 (int i); 
    if (i <= 1)
      return 0;
    else
      return log2(i/2) + 1;
  endfunction

This function is recursive, because it calls itself. It works using these two truths:

  1. the log base 2 of 1 is 0
  2. the log base 2 of any number is the log base 2 of half that number plus 1

You need this for your testbench, but you will find that this function is actually synthesisable.


https://www.edaplayground.com/x/3bTN

module xyz;

  function int log2 (int i); 
    if (i <= 1)
      return 0;
    else
      return log2(i/2) + 1;
  endfunction

  initial
    begin
      int len;
      for (int i = 1; i <= 65535; i++)
        begin
          len = log2(i)+1;
          $display("i=%d, len=%d", i, len);
        end
    end

endmodule

Upvotes: 1

Related Questions