Reputation: 354
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
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
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
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:
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