How to retrieve the size of a vector

B

Ben

Guest
Hello everybody,

I have little verilog problem,
I have two values (for instance 15 and 25) and I would like to define
another parameter which would be equal to the length of the binary
vector (ADDX1+ADDX2).

parameter ADDX1 = 15;
parameter ADDX2 = 25;
parameter ADD_LENGTH = ????;

Does somebody know if it is possible to do so in verilog ?

Cordially

Ben
 
Ben wrote:
Hello everybody,

I have little verilog problem,
I have two values (for instance 15 and 25) and I would like to define
another parameter which would be equal to the length of the binary
vector (ADDX1+ADDX2).

parameter ADDX1 = 15;
parameter ADDX2 = 25;
parameter ADD_LENGTH = ????;

Does somebody know if it is possible to do so in verilog ?

Cordially

Ben
You need a "constant function" introduced in Verilog 2001. Do a
google search for clogb2 and you should fund many hits on the
function. You'd use "parameter ADD_LENGTH = clogb2( ADDX1+ADDX2 );"

- John_H
 
John_H wrote:
You need a "constant function" introduced in Verilog 2001. Do a
google search for clogb2 and you should fund many hits on the
function. You'd use "parameter ADD_LENGTH = clogb2( ADDX1+ADDX2 );"
One caveat - check how the function works for 2^n numbers. You may
want clog( ADDX1+ADDX2+1 ) instead.

- John_H
 
sndbndr@gmail.com wrote:
In case you don't have access to the Verilog standard, you can use
this function...

function integer log2;
input [31:0] value;
begin
value = value-1;
for (log2=0; value>0; log2=log2+1)
value = value>>1;
end
endfunction

You can call constant functions before they are declared, so you may
use it with parameter declarations and port width expressions.

-Pete

I think Verilog-2005 has a $clog2() function built in, but whether it's
supported by the tools is another question. -Kevin
 
In case you don't have access to the Verilog standard, you can use
this function...

function integer log2;
input [31:0] value;
begin
value = value-1;
for (log2=0; value>0; log2=log2+1)
value = value>>1;
end
endfunction

You can call constant functions before they are declared, so you may
use it with parameter declarations and port width expressions.

-Pete
 
On May 29, 11:40 pm, Kevin Neilson
<kevin_neil...@removethiscomcast.net> wrote:
sndb...@gmail.com wrote:
In case you don't have access to the Verilog standard, you can use
this function...

function integer log2;
input [31:0] value;
begin
value = value-1;
for (log2=0; value>0; log2=log2+1)
value = value>>1;
end
endfunction

You can call constant functions before they are declared, so you may
use it with parameter declarations and port width expressions.

-Pete

I think Verilog-2005 has a $clog2() function built in, but whether it's
supported by the tools is another question. -Kevin

Thank you very much for all your efficient answers !!!
You saved me from a very painful task...

As I must be Verilog-1995 compliant, I have used Pete's solution.

-Ben
 
Ben wrote:
On May 29, 11:40 pm, Kevin Neilson
kevin_neil...@removethiscomcast.net> wrote:
sndb...@gmail.com wrote:
In case you don't have access to the Verilog standard, you can use
this function...
function integer log2;
input [31:0] value;
begin
value = value-1;
for (log2=0; value>0; log2=log2+1)
value = value>>1;
end
endfunction
You can call constant functions before they are declared, so you may
use it with parameter declarations and port width expressions.
-Pete
I think Verilog-2005 has a $clog2() function built in, but whether it's
supported by the tools is another question. -Kevin


Thank you very much for all your efficient answers !!!
You saved me from a very painful task...

As I must be Verilog-1995 compliant, I have used Pete's solution.

-Ben
I don't think Pete's solution (the equivalent of the clogb2 function I
pointed out earlier) will work for you.

The constant function that allows the manipulation of the parameters
during synthesis is a Verilog-2001 construct. Is Verilog-1995 really
where you need to be?!

If you do the google search I suggested, the first hit is a paper that
discusses the new features of Verilog 2001.

- John_H
 
On May 30, 3:04 pm, John_H <newsgr...@johnhandwork.com> wrote:
Ben wrote:
On May 29, 11:40 pm, Kevin Neilson
kevin_neil...@removethiscomcast.net> wrote:
sndb...@gmail.com wrote:
In case you don't have access to the Verilog standard, you can use
this function...
function integer log2;
input [31:0] value;
begin
value = value-1;
for (log2=0; value>0; log2=log2+1)
value = value>>1;
end
endfunction
You can call constant functions before they are declared, so you may
use it with parameter declarations and port width expressions.
-Pete
I think Verilog-2005 has a $clog2() function built in, but whether it's
supported by the tools is another question. -Kevin

Thank you very much for all your efficient answers !!!
You saved me from a very painful task...

As I must be Verilog-1995 compliant, I have used Pete's solution.

-Ben

I don't think Pete's solution (the equivalent of the clogb2 function I
pointed out earlier) will work for you.

The constant function that allows the manipulation of the parameters
during synthesis is a Verilog-2001 construct. Is Verilog-1995 really
where you need to be?!

If you do the google search I suggested, the first hit is a paper that
discusses the new features of Verilog 2001.

- John_H
Thank you for your reply John_H, so I don't think there is a solution
to do that in Verilog-1995. If it has been introduced in 2001, I
assume it was for a good reason.

-Ben
 
Ben wrote:
On May 30, 3:04 pm, John_H <newsgr...@johnhandwork.com> wrote:
Ben wrote:
On May 29, 11:40 pm, Kevin Neilson
kevin_neil...@removethiscomcast.net> wrote:
sndb...@gmail.com wrote:
In case you don't have access to the Verilog standard, you can use
this function...
function integer log2;
input [31:0] value;
begin
value = value-1;
for (log2=0; value>0; log2=log2+1)
value = value>>1;
end
endfunction
You can call constant functions before they are declared, so you may
use it with parameter declarations and port width expressions.
-Pete
I think Verilog-2005 has a $clog2() function built in, but whether it's
supported by the tools is another question. -Kevin
Thank you very much for all your efficient answers !!!
You saved me from a very painful task...
As I must be Verilog-1995 compliant, I have used Pete's solution.
-Ben
I don't think Pete's solution (the equivalent of the clogb2 function I
pointed out earlier) will work for you.

The constant function that allows the manipulation of the parameters
during synthesis is a Verilog-2001 construct. Is Verilog-1995 really
where you need to be?!

If you do the google search I suggested, the first hit is a paper that
discusses the new features of Verilog 2001.

- John_H

Thank you for your reply John_H, so I don't think there is a solution
to do that in Verilog-1995. If it has been introduced in 2001, I
assume it was for a good reason.

-Ben

I remembered--I did have a lame Verilog 1995 solution that I used for
the many years after 2001 that some tools didn't support constant
functions. I found it in an old email. Check it out:

// The define below yields ceil(log2(x)). It's a define instead of a
function
// becuase (certain unnamed tools) don't handle constant functions.
`define CLOG2(x) x<=1?0 :x<=2?1 :x<=4?2: x<=8?3: x<=16?4: x<=32?5:
x<=64?6: x<=128?7: x<=256?8: x<=512?9: x<=1024?10: x<=2048?11:
x<=4096?12: x<=8192?13: x<=16384?14: x<=32768?15: x<=65536?16: 17

To use it in a port width declaration, use it like this:

module xl_adj_delay
#(parameter
MAXDELAY =32, // maximum delay desired
NBITS_OUT = 2, // # of bits of output
BINPT_OUT = 14, // loc of bin. point
SIGND_OUT = 1, // 0 = unsigned
DLY_WIDTH=`CLOG2(MAXDELAY)) // local parameter; don't overwrite
(
input clk, // input clock
input ce, // system clock enable
input en, // user clock enable
input [DLY_WIDTH-1:0] dly_val, // delay will be (dly_val+1) cycles;
8 bits
input [NBITS_OUT-1:0] din, // data input bus
output signed [NBITS_OUT-1:0] dout // delayed output bus
);

-Kevin
 
Ben wrote:
Thank you for your reply John_H, so I don't think there is a solution
to do that in Verilog-1995. If it has been introduced in 2001, I
assume it was for a good reason.

-Ben
*One* solution would be if you know your vector size is going to be
within a specific range:

parameter S = ADDX1 + ADDX2; // just to make the line below shorter
parameter ADD_LENTGH = (S>0)+(S>1)+(S>3)+(S>7)+(S>15)+(S>31)+(S>63)+
(S>127);

You can use a more limited range such as

parameter ADD_LENTGH = 5+(S>31)+(S>63)+(S>127);

and/or use conditional operators if you're wary about adding
comparisons:

parameter ADD_LENGTH = S>127 ? 8 : S>63 ? 7 : S>31 ? 6 : 5;

These forms should work with Verilog-1995. You just have to know the
limits you intend to work with. It's nowhere near as pretty as
clogb2(ADDX1+ADDX2) but it works.

- John_H
 
John_H wrote:
Kevin Neilson wrote:
....
`define CLOG2(x) x<=1?0 :x<=2?1 :x<=4?2: x<=8?3: x<=16?4: x<=32?5:
x<=64?6: x<=128?7: x<=256?8: x<=512?9: x<=1024?10: x<=2048?11:
x<=4096?12: x<=8192?13: x<=16384?14: x<=32768?15: x<=65536?16: 17
....

It's certainly prettier (in the module) to use the in-line version of
the macro.

For the case of finding the width, either change the CLOG2 <=
instances to < or use 'CLOG2(ADDX1+ADDX2+1) to get the width of the
resulting sum. A sum of 32 needs to return a width of 6 while 31
returns a 5.

Thanks for the pointer, Kevin.

- John_H
I think most tools support the macro with arguments; it's worked for me.
The line with the definition must be a single line of text (it got
wrapped here) unless you use the \ for line continuation. -Kevin
 
Kevin Neilson wrote:
I remembered--I did have a lame Verilog 1995 solution that I used for
the many years after 2001 that some tools didn't support constant
functions. I found it in an old email. Check it out:

// The define below yields ceil(log2(x)). It's a define instead of a function
// because (certain unnamed tools) don't handle constant functions.
`define CLOG2(x) x<=1?0 :x<=2?1 :x<=4?2: x<=8?3: x<=16?4: x<=32?5:
x<=64?6: x<=128?7: x<=256?8: x<=512?9: x<=1024?10: x<=2048?11:
x<=4096?12: x<=8192?13: x<=16384?14: x<=32768?15: x<=65536?16: 17

To use it in a port width declaration, use it like this:

module xl_adj_delay
#(parameter
MAXDELAY =32, // maximum delay desired
NBITS_OUT = 2, // # of bits of output
BINPT_OUT = 14, // loc of bin. point
SIGND_OUT = 1, // 0 = unsigned
DLY_WIDTH=`CLOG2(MAXDELAY)) // local parameter; don't overwrite
(
input clk, // input clock
input ce, // system clock enable
input en, // user clock enable
input [DLY_WIDTH-1:0] dly_val, // delay will be (dly_val+1) cycles;
8 bits
input [NBITS_OUT-1:0] din, // data input bus
output signed [NBITS_OUT-1:0] dout // delayed output bus
);

-Kevin

It's certainly prettier (in the module) to use the in-line version of
the macro.

For the case of finding the width, either change the CLOG2 <=
instances to < or use 'CLOG2(ADDX1+ADDX2+1) to get the width of the
resulting sum. A sum of 32 needs to return a width of 6 while 31
returns a 5.

Thanks for the pointer, Kevin.

- John_H
 

Welcome to EDABoard.com

Sponsor

Back
Top