How to define a counter whose width is big enough to hold in

W

Weng Tianxiang

Guest
Hi,

I have a constant N = 27, how to define a counter whose width is big enough to hold integer 27?

Or how to get a constant = log N? Where "log" is a logarithm with base 2.

Thank you.

Weng
 
On Friday, March 4, 2016 at 5:34:42 AM UTC-8, Gabor wrote:
Weng Tianxiang wrote:
Hi,

I have a constant N = 27, how to define a counter whose width is big enough to hold integer 27?

Or how to get a constant = log N? Where "log" is a logarithm with base 2.

Thank you.

Weng

The function you want is the ceiling of log base 2. In Verilog
this is $clog2(). If you don't have a similar function it's quite
easy to make, since it's generally accomplished by shifting the
input value right until it becomes zero and counting the shifts
required to get there.

--
Gabor

Hi Gabor,

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a known largest number N

Thank you.

Weng
 
Weng Tianxiang wrote:
Hi,

I have a constant N = 27, how to define a counter whose width is big enough to hold integer 27?

Or how to get a constant = log N? Where "log" is a logarithm with base 2.

Thank you.

Weng

The function you want is the ceiling of log base 2. In Verilog
this is $clog2(). If you don't have a similar function it's quite
easy to make, since it's generally accomplished by shifting the
input value right until it becomes zero and counting the shifts
required to get there.

--
Gabor
 
On Friday, March 4, 2016 at 1:20:19 PM UTC-5, Weng Tianxiang wrote:
I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a known largest number N

What exactly is the issue? ieee.math_real defines a log2 function that can be used to define the upper bound. Actually what you want is
ceil(log2(N))

Kevin
 
In article <nbcq1j$i1q$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 3/4/2016 1:20 PM, Weng Tianxiang wrote:
On Friday, March 4, 2016 at 5:34:42 AM UTC-8, Gabor wrote:
Weng Tianxiang wrote:
Hi,

I have a constant N = 27, how to define a counter whose width is big enough to hold integer 27?

Or how to get a constant = log N? Where "log" is a logarithm with base 2.

Thank you.

Weng

The function you want is the ceiling of log base 2. In Verilog
this is $clog2(). If you don't have a similar function it's quite
easy to make, since it's generally accomplished by shifting the
input value right until it becomes zero and counting the shifts
required to get there.

--
Gabor

Hi Gabor,

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a known largest number N

I don't think you need a ceiling function. I think you need a floor
function and add 1. log2(8) = 3.0, log2(9) = 3.17, both need 4 bits to
represent them in binary. A ceiling function will return 3 for 8 and 4
for 9. So it would be

ceiling(log2(8+1)) = 4;

What's the trouble?

Regards,

Mark
 
On Friday, March 4, 2016 at 2:27:55 PM UTC-8, rickman wrote:
On 3/4/2016 5:03 PM, Mark Curry wrote:
In article <nbcq1j$i1q$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 3/4/2016 1:20 PM, Weng Tianxiang wrote:
On Friday, March 4, 2016 at 5:34:42 AM UTC-8, Gabor wrote:
Weng Tianxiang wrote:
Hi,

I have a constant N = 27, how to define a counter whose width is big enough to hold integer 27?

Or how to get a constant = log N? Where "log" is a logarithm with base 2.

Thank you.

Weng

The function you want is the ceiling of log base 2. In Verilog
this is $clog2(). If you don't have a similar function it's quite
easy to make, since it's generally accomplished by shifting the
input value right until it becomes zero and counting the shifts
required to get there.

--
Gabor

Hi Gabor,

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a known largest number N

I don't think you need a ceiling function. I think you need a floor
function and add 1. log2(8) = 3.0, log2(9) = 3.17, both need 4 bits to
represent them in binary. A ceiling function will return 3 for 8 and 4
for 9. So it would be

ceiling(log2(8+1)) = 4;

What's the trouble?

This can work if you add the 1 first, but the number you want is 3. So
you have to subtract 1 from this result. Which is simpler?

Personally I prefer the simpler approach of flog2(N) rather than
clog2(N+1)-1 to get where this needs to go. flog2 is a very simple
function to write. If you use floating point routines for log2 and
ceiling you need to then convert to integer. Are there integer
functions for these routines or do you need to write them? I guess that
wouldn't make sense since log2 either returns a floating point number or
does some form of truncation or rounding.

--

Rick

Hi Gabor, KJ, Rich and Mark,

After your posts, I realized that a user-defined function's returned integer value can be used as boundary limit!!! Before the post I didn't know it.

So I decided to accept Gabor's method to write an integer function log2(integer N) in my design so that it can be repeatedly used later for my life.

Thank you.

Weng

Here is the code:

-- = floor of log2(); log2(27) = 5.

function log2(integer: N) return integer is
variable K : integer;
variable M : integer; -- = M mod 2
begin
K := 0;
M := N;
loop1: while M /= 0 loop
M := M mod 2; -- it cannot use M := M srl 2, because N is an integer
K := K+1;
end loop;

return K;
end log2;

-- to be debugged
 
On 3/4/2016 1:20 PM, Weng Tianxiang wrote:
On Friday, March 4, 2016 at 5:34:42 AM UTC-8, Gabor wrote:
Weng Tianxiang wrote:
Hi,

I have a constant N = 27, how to define a counter whose width is big enough to hold integer 27?

Or how to get a constant = log N? Where "log" is a logarithm with base 2.

Thank you.

Weng

The function you want is the ceiling of log base 2. In Verilog
this is $clog2(). If you don't have a similar function it's quite
easy to make, since it's generally accomplished by shifting the
input value right until it becomes zero and counting the shifts
required to get there.

--
Gabor

Hi Gabor,

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a known largest number N

I don't think you need a ceiling function. I think you need a floor
function and add 1. log2(8) = 3.0, log2(9) = 3.17, both need 4 bits to
represent them in binary. A ceiling function will return 3 for 8 and 4
for 9. So it would be

signal Count : unsigned(flog2(N) downto 0);

Writing flog2(N) should be trivial.

--

Rick
 
On 3/4/2016 3:08 PM, KJ wrote:
On Friday, March 4, 2016 at 1:20:19 PM UTC-5, Weng Tianxiang wrote:

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a known largest number N


What exactly is the issue? ieee.math_real defines a log2 function that can be used to define the upper bound. Actually what you want is
ceil(log2(N))

Isn't it a floor function that is required? Floor and add one. No?

--

Rick
 
On 3/4/2016 5:03 PM, Mark Curry wrote:
In article <nbcq1j$i1q$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 3/4/2016 1:20 PM, Weng Tianxiang wrote:
On Friday, March 4, 2016 at 5:34:42 AM UTC-8, Gabor wrote:
Weng Tianxiang wrote:
Hi,

I have a constant N = 27, how to define a counter whose width is big enough to hold integer 27?

Or how to get a constant = log N? Where "log" is a logarithm with base 2.

Thank you.

Weng

The function you want is the ceiling of log base 2. In Verilog
this is $clog2(). If you don't have a similar function it's quite
easy to make, since it's generally accomplished by shifting the
input value right until it becomes zero and counting the shifts
required to get there.

--
Gabor

Hi Gabor,

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a known largest number N

I don't think you need a ceiling function. I think you need a floor
function and add 1. log2(8) = 3.0, log2(9) = 3.17, both need 4 bits to
represent them in binary. A ceiling function will return 3 for 8 and 4
for 9. So it would be

ceiling(log2(8+1)) = 4;

What's the trouble?

This can work if you add the 1 first, but the number you want is 3. So
you have to subtract 1 from this result. Which is simpler?

Personally I prefer the simpler approach of flog2(N) rather than
clog2(N+1)-1 to get where this needs to go. flog2 is a very simple
function to write. If you use floating point routines for log2 and
ceiling you need to then convert to integer. Are there integer
functions for these routines or do you need to write them? I guess that
wouldn't make sense since log2 either returns a floating point number or
does some form of truncation or rounding.

--

Rick
 
On 3/4/2016 8:01 PM, Weng Tianxiang wrote:
On Friday, March 4, 2016 at 2:27:55 PM UTC-8, rickman wrote:
On 3/4/2016 5:03 PM, Mark Curry wrote:
In article <nbcq1j$i1q$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 3/4/2016 1:20 PM, Weng Tianxiang wrote:
On Friday, March 4, 2016 at 5:34:42 AM UTC-8, Gabor wrote:
Weng Tianxiang wrote:
Hi,

I have a constant N = 27, how to define a counter whose width is big enough to hold integer 27?

Or how to get a constant = log N? Where "log" is a logarithm with base 2.

Thank you.

Weng

The function you want is the ceiling of log base 2. In Verilog
this is $clog2(). If you don't have a similar function it's quite
easy to make, since it's generally accomplished by shifting the
input value right until it becomes zero and counting the shifts
required to get there.

--
Gabor

Hi Gabor,

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a known largest number N

I don't think you need a ceiling function. I think you need a floor
function and add 1. log2(8) = 3.0, log2(9) = 3.17, both need 4 bits to
represent them in binary. A ceiling function will return 3 for 8 and 4
for 9. So it would be

ceiling(log2(8+1)) = 4;

What's the trouble?

This can work if you add the 1 first, but the number you want is 3. So
you have to subtract 1 from this result. Which is simpler?

Personally I prefer the simpler approach of flog2(N) rather than
clog2(N+1)-1 to get where this needs to go. flog2 is a very simple
function to write. If you use floating point routines for log2 and
ceiling you need to then convert to integer. Are there integer
functions for these routines or do you need to write them? I guess that
wouldn't make sense since log2 either returns a floating point number or
does some form of truncation or rounding.

--

Rick

Hi Gabor, KJ, Rich and Mark,

After your posts, I realized that a user-defined function's returned integer value can be used as boundary limit!!! Before the post I didn't know it.

So I decided to accept Gabor's method to write an integer function log2(integer N) in my design so that it can be repeatedly used later for my life.

Thank you.

Weng

Here is the code:

-- = floor of log2(); log2(27) = 5.

function log2(integer: N) return integer is
variable K : integer;
variable M : integer; -- = M mod 2
begin
K := 0;
M := N;
loop1: while M /= 0 loop
M := M mod 2; -- it cannot use M := M srl 2, because N is an integer
K := K+1;
end loop;

return K;
end log2;

-- to be debugged

I can't recall the last time I wrote even a simple program that was 100%
correct the first time. I think when you debug your program it will
need to be M := M / 2;

You might want to make your comment, "it cannot use M := M srl 1,
because N is an integer"

--

Rick
 
On 3/5/2016 12:23 AM, rickman wrote:
On 3/4/2016 8:01 PM, Weng Tianxiang wrote:
On Friday, March 4, 2016 at 2:27:55 PM UTC-8, rickman wrote:
On 3/4/2016 5:03 PM, Mark Curry wrote:
In article <nbcq1j$i1q$1@dont-email.me>, rickman <gnuarm@gmail.com
wrote:
On 3/4/2016 1:20 PM, Weng Tianxiang wrote:
On Friday, March 4, 2016 at 5:34:42 AM UTC-8, Gabor wrote:
Weng Tianxiang wrote:
Hi,

I have a constant N = 27, how to define a counter whose width is
big enough to hold integer 27?

Or how to get a constant = log N? Where "log" is a logarithm
with base 2.

Thank you.

Weng

The function you want is the ceiling of log base 2. In Verilog
this is $clog2(). If you don't have a similar function it's quite
easy to make, since it's generally accomplished by shifting the
input value right until it becomes zero and counting the shifts
required to get there.

--
Gabor

Hi Gabor,

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a
known largest number N

I don't think you need a ceiling function. I think you need a floor
function and add 1. log2(8) = 3.0, log2(9) = 3.17, both need 4
bits to
represent them in binary. A ceiling function will return 3 for 8
and 4
for 9. So it would be

ceiling(log2(8+1)) = 4;

What's the trouble?

This can work if you add the 1 first, but the number you want is 3. So
you have to subtract 1 from this result. Which is simpler?

Personally I prefer the simpler approach of flog2(N) rather than
clog2(N+1)-1 to get where this needs to go. flog2 is a very simple
function to write. If you use floating point routines for log2 and
ceiling you need to then convert to integer. Are there integer
functions for these routines or do you need to write them? I guess that
wouldn't make sense since log2 either returns a floating point number or
does some form of truncation or rounding.

--

Rick

Hi Gabor, KJ, Rich and Mark,

After your posts, I realized that a user-defined function's returned
integer value can be used as boundary limit!!! Before the post I
didn't know it.

So I decided to accept Gabor's method to write an integer function
log2(integer N) in my design so that it can be repeatedly used later
for my life.

Thank you.

Weng

Here is the code:

-- = floor of log2(); log2(27) = 5.

function log2(integer: N) return integer is
variable K : integer;
variable M : integer; -- = M mod 2
begin
K := 0;
M := N;
loop1: while M /= 0 loop
M := M mod 2; -- it cannot use M := M srl 2, because N is an
integer
K := K+1;
end loop;

return K;
end log2;

-- to be debugged

I can't recall the last time I wrote even a simple program that was 100%
correct the first time. I think when you debug your program it will
need to be M := M / 2;

You might want to make your comment, "it cannot use M := M srl 1,
because N is an integer"

Oh yeah, you also need to change "while M /= 0" to "while M > 1".
Otherwise you will get a return value of 1 for 1, 2 for 2, 3 for 4, 4
for 8, etc, which are all 1 more than the correct value and not optimal
for your use.

--

Rick
 
On Saturday, 5 March 2016 04:08:17 UTC+8, KJ wrote:
On Friday, March 4, 2016 at 1:20:19 PM UTC-5, Weng Tianxiang wrote:

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a known largest number N


What exactly is the issue? ieee.math_real defines a log2 function that can be used to define the upper bound. Actually what you want is
ceil(log2(N))

Kevin

Yes, KJ is right. In code, this would look like (I use this very often in synthesizable code):

signal cnt: u_unsigned(positive(ceil(log2(real(N))))-1 downto 0);
 
On Sunday, 6 March 2016 11:56:54 UTC+8, rickman wrote:
On 3/5/2016 10:20 PM, Daniel Kho wrote:
On Saturday, 5 March 2016 04:08:17 UTC+8, KJ wrote:
On Friday, March 4, 2016 at 1:20:19 PM UTC-5, Weng Tianxiang wrote:

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a known largest number N


What exactly is the issue? ieee.math_real defines a log2 function that can be used to define the upper bound. Actually what you want is
ceil(log2(N))

Kevin

Yes, KJ is right. In code, this would look like (I use this very often in synthesizable code):

signal cnt: u_unsigned(positive(ceil(log2(real(N))))-1 downto 0);

Code like this is why people use Verilog. I'm just sayin'. ;)

Oh, it's also wrong.

--

Rick

Yes, but explicit type conversions are also one of VHDL's strengths. :)
It's better to be explicit in your code when it comes to what types you're using, instead of the tool (or language) doing the conversions implicitly for you - and later on you find out that the implicitly conversions aren't what you want.

- dan
 
On 3/5/2016 10:20 PM, Daniel Kho wrote:
On Saturday, 5 March 2016 04:08:17 UTC+8, KJ wrote:
On Friday, March 4, 2016 at 1:20:19 PM UTC-5, Weng Tianxiang wrote:

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a known largest number N


What exactly is the issue? ieee.math_real defines a log2 function that can be used to define the upper bound. Actually what you want is
ceil(log2(N))

Kevin

Yes, KJ is right. In code, this would look like (I use this very often in synthesizable code):

signal cnt: u_unsigned(positive(ceil(log2(real(N))))-1 downto 0);

Code like this is why people use Verilog. I'm just sayin'. ;)

Oh, it's also wrong.

--

Rick
 
On 3/5/2016 11:23 PM, Daniel Kho wrote:
On Sunday, 6 March 2016 11:56:54 UTC+8, rickman wrote:
On 3/5/2016 10:20 PM, Daniel Kho wrote:
On Saturday, 5 March 2016 04:08:17 UTC+8, KJ wrote:
On Friday, March 4, 2016 at 1:20:19 PM UTC-5, Weng Tianxiang wrote:

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a known largest number N


What exactly is the issue? ieee.math_real defines a log2 function that can be used to define the upper bound. Actually what you want is
ceil(log2(N))

Kevin

Yes, KJ is right. In code, this would look like (I use this very often in synthesizable code):

signal cnt: u_unsigned(positive(ceil(log2(real(N))))-1 downto 0);

Code like this is why people use Verilog. I'm just sayin'. ;)

Oh, it's also wrong.

--

Rick

Yes, but explicit type conversions are also one of VHDL's strengths. :)
It's better to be explicit in your code when it comes to what types you're using, instead of the tool (or language) doing the conversions implicitly for you - and later on you find out that the implicitly conversions aren't what you want.

Over the years I have lived on both sides of the fence. I program
hardware in strongly typed VHDL but when it comes to software I prefer
Forth which has no concept of type. People try to tell me how good
strong typing is and I agree that it can catch problems early that would
not be cause so easily later on, but the verbosity and complexity of
some code is hard to accept. Others just side step that theoretical
issues by pointing out the number of errors made which tools can't catch
such as the one you wrote. You didn't even address that.

Your code has a logical flaw that allocates one bit too few for any
value of N that is a power of 2. I suppose the tools would flag that
when you try to assign a vector of a different size to it... unless you
make a similar mistake elsewhere in which case you won't find out until
in simulation you exercise with the max value. If that doesn't happen
you will have a very hard time trying to figure out why the design
doesn't work correctly in the device.

I'm not trying to knock your code. I'm trying to point out that strong
typing can impact your coding and allow mistakes to be missed because of
the verbosity. Much simpler would be to write a small function to
calculate a vector index max value that would replace the whole
positive(ceil(log2(real(N))))-1 thing.

--

Rick
 
On Sunday, 6 March 2016 14:13:43 UTC+8, rickman wrote:
Your code has a logical flaw that allocates one bit too few for any
value of N that is a power of 2. I suppose the tools would flag that
when you try to assign a vector of a different size to it... unless you
make a similar mistake elsewhere in which case you won't find out until
in simulation you exercise with the max value. If that doesn't happen
you will have a very hard time trying to figure out why the design
doesn't work correctly in the device.

Yes you're right there, for values of N that is a power of 2.
My earlier code should have been:
signal cnt: u_unsigned(positive(ceil(log2(real(N+1))))-1 downto 0);

Personally I prefer the simpler approach of flog2(N) rather than
clog2(N+1)-1 to get where this needs to go. flog2 is a very simple
function to write. If you use floating point routines for log2 and
ceiling you need to then convert to integer. Are there integer
functions for these routines or do you need to write them? I guess that
wouldn't make sense since log2 either returns a floating point number or
does some form of truncation or rounding.

Well, I don't mind writing (log2(N+1)-1), though yes, writing a function can make your life easier.

- daniel
 
On 3/6/2016 2:26 AM, Daniel Kho wrote:
On Sunday, 6 March 2016 14:13:43 UTC+8, rickman wrote:
Your code has a logical flaw that allocates one bit too few for any
value of N that is a power of 2. I suppose the tools would flag that
when you try to assign a vector of a different size to it... unless you
make a similar mistake elsewhere in which case you won't find out until
in simulation you exercise with the max value. If that doesn't happen
you will have a very hard time trying to figure out why the design
doesn't work correctly in the device.

Yes you're right there, for values of N that is a power of 2.
My earlier code should have been:
signal cnt: u_unsigned(positive(ceil(log2(real(N+1))))-1 downto 0);

Personally I prefer the simpler approach of flog2(N) rather than
clog2(N+1)-1 to get where this needs to go. flog2 is a very simple
function to write. If you use floating point routines for log2 and
ceiling you need to then convert to integer. Are there integer
functions for these routines or do you need to write them? I guess that
wouldn't make sense since log2 either returns a floating point number or
does some form of truncation or rounding.

Well, I don't mind writing (log2(N+1)-1), though yes, writing a function can make your life easier.

I hope I'm not belaboring the point too much, but it's not
(log2(N+1)-1), it's (positive(ceil(log2(real(N+1))))-1) vs. flog2(N).

I think I developed an aversion to the long windiness of VHDL when I was
initially learning it and didn't fully understand the typing. Also it
was a bit harder back then when "10011" would not be recognized as an
SLV and had to be specified as SLV. Trying to convert types all the
time in efficient ways was a PITA. So I learned to write my own
conversions that did it in a minimum of layers.

VHDL 2008 is better now with a lot of type issues gone. I still like to
eliminate long function chains like the floating point calculation used
here to count bits.

--

Rick
 
On 3/4/2016 8:25 AM, Weng Tianxiang wrote:
Hi,

I have a constant N = 27, how to define a counter whose width is big enough to hold integer 27?

Have you considered this?

signal Count : integer range 0 to N;

--

Rick
 
On Friday, March 4, 2016 at 8:01:50 PM UTC-5, Weng Tianxiang wrote:
Here is the code:

-- = floor of log2(); log2(27) = 5.

function log2(integer: N) return integer is
variable K : integer;
variable M : integer; -- = M mod 2
begin
K := 0;
M := N;
loop1: while M /= 0 loop
M := M mod 2; -- it cannot use M := M srl 2, because N is an integer
K := K+1;
end loop;

return K;
end log2;

M := M mod 2 is not correct. You want to divide M by 2 (M := M / 2) instead.

> -- to be debugged

Or, rather than reinventing and debugging the wheel, Google yourself over to http://www.vhdl.org/comp.lang.vhdl/FAQ1.html to find the solution. There are two log2 algorithms implemented, one uses recursive calls to a log2 function, the other uses a while loop. Both claim to be synthesizable in working with constants, the recursive version I can vouch works with signals as well (i.e. Log_Sig1 <= log2(Sig1);)

Kevin Jennings
 
On Friday, March 4, 2016 at 10:48:11 PM UTC-8, rickman wrote:
On 3/5/2016 12:23 AM, rickman wrote:
On 3/4/2016 8:01 PM, Weng Tianxiang wrote:
On Friday, March 4, 2016 at 2:27:55 PM UTC-8, rickman wrote:
On 3/4/2016 5:03 PM, Mark Curry wrote:
In article <nbcq1j$i1q$1@dont-email.me>, rickman <gnuarm@gmail.com
wrote:
On 3/4/2016 1:20 PM, Weng Tianxiang wrote:
On Friday, March 4, 2016 at 5:34:42 AM UTC-8, Gabor wrote:
Weng Tianxiang wrote:
Hi,

I have a constant N = 27, how to define a counter whose width is
big enough to hold integer 27?

Or how to get a constant = log N? Where "log" is a logarithm
with base 2.

Thank you.

Weng

The function you want is the ceiling of log base 2. In Verilog
this is $clog2(). If you don't have a similar function it's quite
easy to make, since it's generally accomplished by shifting the
input value right until it becomes zero and counting the shifts
required to get there.

--
Gabor

Hi Gabor,

I want to use the (log N) to be the width of a counter:

signal Count : unsigned((log N)-1 downto 0); -- it can hold a
known largest number N

I don't think you need a ceiling function. I think you need a floor
function and add 1. log2(8) = 3.0, log2(9) = 3.17, both need 4
bits to
represent them in binary. A ceiling function will return 3 for 8
and 4
for 9. So it would be

ceiling(log2(8+1)) = 4;

What's the trouble?

This can work if you add the 1 first, but the number you want is 3. So
you have to subtract 1 from this result. Which is simpler?

Personally I prefer the simpler approach of flog2(N) rather than
clog2(N+1)-1 to get where this needs to go. flog2 is a very simple
function to write. If you use floating point routines for log2 and
ceiling you need to then convert to integer. Are there integer
functions for these routines or do you need to write them? I guess that
wouldn't make sense since log2 either returns a floating point number or
does some form of truncation or rounding.

--

Rick

Hi Gabor, KJ, Rich and Mark,

After your posts, I realized that a user-defined function's returned
integer value can be used as boundary limit!!! Before the post I
didn't know it.

So I decided to accept Gabor's method to write an integer function
log2(integer N) in my design so that it can be repeatedly used later
for my life.

Thank you.

Weng

Here is the code:

-- = floor of log2(); log2(27) = 5.

function log2(integer: N) return integer is
variable K : integer;
variable M : integer; -- = M mod 2
begin
K := 0;
M := N;
loop1: while M /= 0 loop
M := M mod 2; -- it cannot use M := M srl 2, because N is an
integer
K := K+1;
end loop;

return K;
end log2;

-- to be debugged

I can't recall the last time I wrote even a simple program that was 100%
correct the first time. I think when you debug your program it will
need to be M := M / 2;

You might want to make your comment, "it cannot use M := M srl 1,
because N is an integer"

Oh yeah, you also need to change "while M /= 0" to "while M > 1".
Otherwise you will get a return value of 1 for 1, 2 for 2, 3 for 4, 4
for 8, etc, which are all 1 more than the correct value and not optimal
for your use.

--

Rick

Hi Rick,
I just want to 1 for 1, 2 for 2, 3 for 4, 4 for 8, the bit count that is big enough to hold N.

signal Counter : unsigned(log2(N)-1 downto 0);

I don't want to skip "-1", because all unsigned() expressions in my design uses format name(xxx-1 downto 0);

for all integer M mod 2 == M / 2, but latter is better than former.

So actually my design has no error at all!!!

Weng
 

Welcome to EDABoard.com

Sponsor

Back
Top