# how to calculate log2(n) in verilog

1. ## how to calculate log2(n) in verilog

Hiii •

2. ## Re: how to calculate log2(n) in verilog

Code:
```function integer clogb2;
input [31:0] value;
integer 	i;
begin
clogb2 = 0;
for(i = 0; 2**i < value; i = i + 1)
clogb2 = i + 1;
end
endfunction```

1 members found this post helpful. 3. ## Re: how to calculate log2(n) in verilog

Thanks alot RBB. I hope my code starts behaving well now. Thanks again. 4. ## Re: how to calculate log2(n) in verilog

Dear RBB

The function code you gave me is good but i cant call it. Im simply trying to calculate the log base 2 of 26 n save it to a register n_var. Please correct this code for me. Its as follows

module sample11(n_var);

output [15:0]n_var;
n_var = clogb2(26);

function integer clogb2;
input [31:0] value;
integer i;
begin
clogb2 = 0;
for(i = 0; 2**i < value; i = i + 1)
clogb2 = i + 1;
end
endfunction

endmodule

Thanks alot 5. ## Re: how to calculate log2(n) in verilog

Code:
```module sample11(v,n_var);

input  [15:0]v;
output [15:0]n_var;

wire [15:0] v;
reg [15:0]n_var;
reg [15:0]value;

always @ (v)
n_var = clogb2(v);

function integer clogb2;
input [31:0] value;
integer i;
begin
clogb2 = 0;
for(i = 0; 2**i < value; i = i + 1)
clogb2 = i + 1;
end
endfunction

endmodule```

it is a simple testbench:

Code:
```module test();

reg [15:0] v;
reg i;
wire [15:0] n_var;

sample11 s1(v,n_var);

initial
v = 2;

initial
#2000 \$finish;

always
begin
#5 v = v+1;
end

always @ (v)
\$monitor ("log%d = %d", v, n_var);

endmodule```

1 members found this post helpful. •

6. ## Re: how to calculate log2(n) in verilog

Dear meher81

Thankyou very much for your code. It simulates great. I just have to figure out a thing or two in it. Thanks alot.

Im stuck in another little piece of code now. I wondr if you can help me with it. Its supposed to scan an array for 16 elements and calculate the maximum value. Its as follows:

module maxvalue(b_array);

input [0:15] b_array;
integer i;
reg [0:15] mxm;

initial
begin
mxm = 16'b0;

for (i=0;i<15;i=i+1)
begin
if (b_array[i] > mxm)
mxm = b_array[i];
end
end

endmodule

I just cant figure out how to write the testbench for it. I gave initial values to the b_array in the tb as follows:

module max11_tb();

// Inputs
reg [0:15] b_array;

// Instantiate the Unit Under Test (UUT)
maxvalue uut (
.b_array(b_array)
);

initial begin
// Initialize Inputs
b_array = 13;
b_array = 1;
b_array = 2;
b_array =14;
b_array =12;
b_array =0;
b_array =-1;
b_array =21;
b_array =12;
b_array =2;
b_array =-4;
b_array =0;
b_array =9;
b_array =13;
b_array =10;
b_array =-2;

// Wait 100 ns for global reset to finish
#100;

end

endmodule

It isnt giving me the largest value as expected.
Please let me know if you can find a solution to it. Thanks alot 7. ## Re: how to calculate log2(n) in verilog

Dear UFK
Verilog doesn't allow an I/O port to be a 2-D array.
but if it it is necessary, you could flatten your array into a vector and pass that through the port.
Code:
```module maxvalue(
b_array,
mxm,
reset
);

input  [255:0] b_array;
input reset;
output [15:0] mxm;

reg  [15:0] array [0:15];
integer i;
reg [15:0] mxm;

always @ (b_array)
begin
if (reset)
mxm = 0;

{array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array}=b_array;

for (i=0;i<16;i=i+1)
if (array[i] > mxm)
mxm = array [i];
end

endmodule```
simple test module
Code:
```module max11_tb();

reg  [255:0] b_array;
wire [15:0] max;
reg reset;

maxvalue uut (
.b_array(b_array),
.mxm (max),
.reset (reset)
);

initial
begin
reset = 1;
#10 reset = 0;
end

initial
begin
#7 b_array = 255'd1;
#10 b_array = 255'd2;
#15 b_array = 255'd197879804;
#20 b_array = 255'd200000000000000000003;
end

always @ (b_array)
\$monitor  (\$time, "maximum value component = %d", max );

endmodule```

1 members found this post helpful. 8. ## Re: how to calculate log2(n) in verilog

Dear meher81

Thanks alot for your help. You just made my life easier :) •

9. ## Re: how to calculate log2(n) in verilog

Dear meher81

I am using the code u helped me with to scan values in a bram and then calculate maximum value. I stored 16 values in a bram by a coe file. Now im trying to run the following code by invoking the bram (spiht_mem). Since i already gave the values in the coe file i have no clue what to write in the testbench. Can u please help me? Thankyou in advance.

The code is

input [255:0] b_array;
input reset;
output [15:0] mxm;
input clkA;

Spiht_mem M1 (
.clka(clkA),
.wea(), // Bus [0 : 0]
.dina(), // Bus [15 : 0]
.douta(array)); // Bus [15 : 0]

reg [15:0] array [0:15];
integer i;
reg [15:0] mxm;

always @ (b_array)
begin
if (reset)
mxm = 0;
//[15:0] array[0:15]= b_array;
{array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array}=b_array;

for (i=0;i<16;i=i+1)
if (array[i] > mxm)
mxm = array [i];
end

endmodule 10. ## Re: how to calculate log2(n) in verilog

I don't know what you want.
I guess that you have stored some values in a file (as bram.dat) and want to apply them to your code, which detect maximum value. yes? 11. ## Re: how to calculate log2(n) in verilog

Hii meher81

Yes that is exactly what i want. I was testing my algorithm to work for 16 values initially but i wanted my code to work for as many values as i want, say for a 128 x128 image which means that if i load 16384 decimal values in my bram as a .coe file it should call the values from the bram and then scan for the maximum decimal value.
Btw if i call values from the bram using (.dout(w1[0:b]) where w1 is a wire do u think it will work?

Part of my code is like this
reg [31:0] LIS5a [1023:0];
.
.
.
FiveA M1 (.douta(LIS5a));
here FiveA is my bram in which i have loaded a .coe file of 1024 decimal values. I want to call those values so i tried moving them directly in to the reg LIS5a instead of using wire w1. Any suggestions or comments?

Thanks alot for all the help :) 12. ## Re: how to calculate log2(n) in verilog

Dear UFK
you can do this in a testbench. at first, store file content in an array using \$readmemb. after that you can do, with the array elements, what you want. 13. ## Re: how to calculate log2(n) in verilog Originally Posted by meher81
Dear UFK
you can do this in a testbench. at first, store file content in an array using \$readmemb. after that you can do, with the array elements, what you want.
Dear meher81

I did what u suggested and everything worked brilliantly, until i realized that \$readmemh will not take negative hex values from my text file. Im back at square one now ! :(((( Do u have a solution to this problem?
Previously i tried using a bram, but i couldnt figure out how to move its .coe file contents in to my array.
And thanks alot for everything 14. ## Re: how to calculate log2(n) in verilog

Dear UFK

you should change your negative numbers to 2's complement format. (perhaps with MATLAB or manually!) •

15. ## Re: how to calculate log2(n) in verilog

Hii meher81

I did change it to negative format (e.g -1 to FFFFFFFF) and it still isnt quite working. Please do me this big favour. Im posting my code, test bench and txt file. Can u plz run it and see the results? I know ull know wat im doing wrong.

module max_val(mxm,
reset
);
input reset;
output [31:0] mxm;
reg [31:0] Mem [0:3];

integer i;
reg [31:0] mxm;

always @ *
begin
if (reset)
mxm = 0;

for (i=0;i<=3;i=i+1)
if (Mem[i] > mxm)
mxm = Mem [i];
end
endmodule
Testbench
module max_val_tb;

// Inputs
reg reset;

// Outputs
wire [31:0] mxm;

// Instantiate the Unit Under Test (UUT)
max_val uut (
.mxm(mxm),
.reset(reset)
);

initial begin
// Initialize Inputs
reset = 0;

#100;

reset = 1;

end

endmodule
and the text file
//D15 =

29B
043
FFFFFE72
FFFFFEE7

//667
//67
//-398
//-281
wat i figured is that if my text file has the following numbers in hex form i.e -10,-11,-12,10,11,12, the code simply ignores the positive values and computes the maximum of the negative values, for instance in this case it will return -10 which is the max.

Maybe ud know a solution.
And thanks a million for always coming to my rescue :) 16. ## Re: how to calculate log2(n) in verilog

Code:
```module max_val (
mxm,
in,
reset
);
input reset;
input  [ 31 : 0 ] in;

output [ 31 : 0 ] mxm;

wire   [ 31 : 0 ] in;

integer k;
integer i;
integer  mxm;

always @ (in or reset)
begin
if (reset)
mxm = 0;
else
k=in;
if (k>mxm)
mxm <= k;
end

endmodule```
Testbench:
Code:
```module max_val_tb;

wire [31:0] mxm;

reg reset,clk;
reg [31:0] Mem [0:3];

integer i;
integer input_data;

max_val uut (
.mxm(mxm),
.in(input_data),
.reset(reset)
);

initial
begin
reset = 1;
#2 reset = 0;
end

initial
clk =0;

always
#5 clk=~clk;

initial
i=0;

always @ (posedge clk)
begin
input_data = Mem[i];
i = i+1;
\$monitor ("max = %d, input=%d", mxm, input_data);
end

endmodule```

I did that same as you, but in this way, after the reset, mxm is set to zero. therefore this code neglect negative numbers. to solve that, you can do same as below:
Code:
```module max_val (
mxm,
in,
reset
);
input reset;
input  [ 31 : 0 ] in;

output [ 31 : 0 ] mxm;

wire   [ 31 : 0 ] in;

integer k;
integer i;
integer  mxm;

always @ (in or reset)
begin
if (reset)
mxm = 32'h80000001;
else
k=in;
if (k>mxm)
mxm <= k;
end

endmodule```
Testbench:
Code:
```module max_val_tb;

wire [31:0] mxm;

reg reset,clk;
reg [31:0] Mem [0:3];

integer i,m;
integer input_data;

max_val uut (
.mxm(mxm),
.in(input_data),
.reset(reset)
);

initial
begin
reset = 1;
#2 reset = 0;
end

initial
clk =0;

always
#5 clk=~clk;

initial
i=0;

always @ (posedge clk)
begin
input_data = Mem[i];
i = i+1;
m=mxm;
\$monitor ("max = %d, input=%d", m, input_data);
end

endmodule``` 17. ## Re: how to calculate log2(n) in verilog

Dear meher

Maybe you could solve another one of my neverending problems.
Im posting my code below. If possible, Please run it and see if it can be altered to function the way i want. My code isnt reading negative hex values. It only gives correct results for positive hex values. Can anything be done about it?

1. I have two arrays LIP and LSP. readmem will put memory values into LIP.

2. The code is supposed to read the four values from LIP and compare with the parameter T.

3. If greater than T, then move values to LSP.

4. If less than T, then leave it in LIP

5. The bit counters seem to function fine.

My code is

module test();

reg [31:0] Signbit_ctr;
reg [31:0] Bit_ctr0;
reg [31:0] Bit_ctr1;

reg[31:0] T=32'h00001000; //decimal 4096

integer i;
integer k;

reg [31:0] LIP [0:3];
reg [31:0] LSP [0:1023];

initial
begin

Signbit_ctr = 0;
Bit_ctr0 = 0;
Bit_ctr1 = 0;

end

always @ (LIP)
begin
for(i=0;i<=3;i=i+1)

if (LIP[i] >= T)

begin

LSP[i] = LIP[i];

Bit_ctr1 = Bit_ctr1 + 1;
Signbit_ctr = Signbit_ctr + 1;

end
else
begin

Bit_ctr0 = Bit_ctr0 + 1;
\$display("%d:%h",i,LSP[i]);

end

end
endmodule

and the text file D16 is

12F2
FFFFFD3E
FFFFFF78
FF

Thankyou so much 18. ## Re: how to calculate log2(n) in verilog

Dear meher81
I need you help.
Im posting a code which u wrote for me a few months ago. Its a part of my encoder. It just wont synthesize. Maybe you can help.

The code is
module Log_max(v,n_var,T);

input [31:0]v;
output [31:0]n_var;
output reg [31:0] T=0;

wire [31:0] v;
reg [31:0]n_var;
reg [3:0] base = 2;

always @ (v)
n_var = CLogB2(v);

always@(*)
begin
T = base ** n_var;
end

//ceil of the log base 2
function integer CLogB2;
input [31:0] Depth;
integer i;
begin
i = Depth;
for(CLogB2 = 0; i > 1; CLogB2 = CLogB2 + 1)
i = i >> 1;
end
endfunction
endmodule
Testbench

module Log_max_tb;

// Inputs
reg [31:0] v;

// Outputs
wire [31:0] n_var;
wire [31:0] T;

// Instantiate the Unit Under Test (UUT)
Log_max uut (
.v(v),
.n_var(n_var),
.T(T)
);

initial begin
// Initialize Inputs
v = 32'h00000B43;

end

endmodule 