shaiko
Advanced Member level 5
- Joined
- Aug 20, 2011
- Messages
- 2,644
- Helped
- 303
- Reputation
- 608
- Reaction score
- 297
- Trophy points
- 1,363
- Activity points
- 18,302
x: out unsigned ( positive ( floor ( log2 ( real ( y ) ) ) ) downto 0 ) ;
y : positive := 8 ;
A floating point rounding issue with Modelsim. The ieee.math_real.log2(8) is slightly less than 3 when Modelsim does the calculation so the ieee.math_real.floor function then truncates it to 2, see transcript below.What's wrong here?
If you instead use the synthesizable version of log2 which only works with integers, it returns the correct result.
# work.pkg_Vhd_Common.log2=3
# work.pkg_Vhd_Common.log2(7)=2
# work.pkg_Vhd_Common.log2(8)=3
# work.pkg_Vhd_Common.log2(9)=3
That's what ceil_log2 will compute, the exact size you need.I don't want to use the ceil_log2 function. I need the port to be sized exactly to accommodate the desired width.
- It is not a standard package. It is something that most folks stumble across with Google.1. Is it a standard package?
2. What's the name of the package?
3. If it works with integers it should also work with positives - correct ?
Here is a link to somebody who posts both a 'simpler' form of log2 which is basically what you have posted in this forum. This guy though posted results from Python, did not post his VHDL results.
http://noasic.com/blog/a-simpler-log2-function/
Kevin, That link does (now) show two versions of the log2 function a floating point and a integer version following the Python one.
That's what ceil_log2 will compute, the exact size you need.
Maybe it'll work in the particular case I presented - but in other cases it'll calculate a result that's 1 bit longer then what I need.Since you are using the log2 to define bit widths, you most likely want to do the ceil(log2()) rather than the floor(log2()).
Maybe it'll work in the particular case I presented - but in other cases it'll calculate a result that's 1 bit longer then what I need.
suppose I want to set the boundaries of 14 (binary 1110).
log2 ( 14.0 ) = 3.85...
And
ceil ( 3.85 ) = 4
So...
ceil ( log2 ( 14.0 ) ) = 4 ;
But obviously "1110" is a ( 3 downto 0 ) vector - not a ( 4 downto 0 ) vector.
Please explain what you meant.
signal xyz: unsigned(ceil_log2(N)-1 downto 0);
I don't see how...in fact what it returns is the number of bits that you need to represent 'N'.
I don't see how...
Consider that N=4 which is binary: "100" (3 bits total)
ceil_log2 ( 4 ) = 2
but obviously you need 3 bits to represent N - not 2...
positive ( floor ( log2 ( real ( x ) ) ) )
I'll try to make it clearer
I have a generic number - call it x.
I want to define port y so it will be able to accommodate numbers smaller or equal to x
Therefore, I need a function (or combination of functions) that calculate the binary position of the MSB of x.
For example:
x = 8 ---> "1000". function returns 3
x = 7 ---> "111". function returns 2
x = 2 ---> "10". function returns 1.
My combination of:
Does just that!Code:positive ( floor ( log2 ( real ( x ) ) ) )
However, because of a modalism bug it doesn't work correctly...
Help me rewrite a function that does the same thing.
Code VHDL - [expand] 1 2 3 -- gives you the number of bits required to hold the value (you keep getting stuck here for some reason): -- e.g x = 8 ---> "1000", there are 4 bits. integer ( ceil ( log2 ( real (x) ) ) )
Code VHDL - [expand] 1 2 3 -- gives you the bit position of the most significant bit (refer back to posts #8 & #10 by K-J): -- e.g. x = 8 ---> "1000", the 1 is located in bit position 3 of a 4-bit wide value. integer ( ceil ( log2 ( real (x) ) ) ) - 1
-- gives you the number of bits required to hold the value (you keep getting stuck here for some reason):
-- e.g x = 8 ---> "1000", there are 4 bits.
integer ( ceil ( log2 ( real (x) ) ) )
-- gives you the bit position of the most significant bit (refer back to posts #8 & #10 by K-J):
-- e.g. x = 8 ---> "1000", the 1 is located in bit position 3 of a 4-bit wide value.
integer ( ceil ( log2 ( real (x) ) ) ) - 1
I'll try to make it clearer
I have a generic number - call it x.
I want to define port y so it will be able to accommodate numbers smaller or equal to x
Therefore, I need a function (or combination of functions) that calculate the binary position of the MSB of x.
For example:
x = 8 ---> "1000". function returns 3
x = 7 ---> "111". function returns 2
x = 2 ---> "10". function returns 1.
My combination of:
Does just that!Code:positive ( floor ( log2 ( real ( x ) ) ) )
However, because of a modalism bug it doesn't work correctly...
Help me rewrite a function that does the same thing.
entity My_Entity is generic (N: positive);
port(
Inp_Integer: in natural range 0 to N-1;
Out_unsigned: out unsigned(ceil_log2(N)-1 downto 0)
);
end My_Entity;
function ceil_log2(x : positive) return natural is
begin
if x <= 1 then
return 0;
else
return ceil_log2(x / 2) + 1;
end if;
end function ceil_log2;
ceil ( log2 ( real ( x ) ) ) -- uses the math.real log2 function
function ceil_log2(x : positive) return natural is
begin
if x <= 1 then
return 0;
else
return ceil_log2(x / 2) + 1;
end if;
end function ceil_log2;
ceil ( log2 ( real ( x ) ) ) -- uses the math.real log2 function
function ceil_log2 (Arg : positive) return natural is
variable RetVal: natural;
begin
RetVal := log2(Arg);
if (Arg > (2**RetVal)) then
return(RetVal + 1); -- RetVal is too small, so bump it up by 1 and return
else
return(RetVal); -- Just right
end if;
end function ceil_log2;
But the oldest reference that I know of is from the venerable FAQ for comp.lang.vhdl at **broken link removed** which lists both a recursive version (which is what I use), as well as the iterative version from Ray Andraka.
function ceil_log2(x : positive) return natural is
begin
if x <= 1 then
return 0;
else
return ceil_log2(x / 2) + 1;
end if;
end function ceil_log2;
On the basis of applying it on the number 7 (instead of 8).But in an earlier posting you confirmed that ceil(log2(8.0)) was 3 which is correct. On what basis are you saying that the code is not correct?
Post #4
This is the recursive version - and you said that you use it. Therefore I attributed it to you and understood that this is how your "ceil_log2" works.
On the basis of applying it on the number 7 (instead of 8).
ceil(log2(7)) = 3
7 is "111" so the MSB's is in position 2 (not 3).
Really appreciate your patience. I'm doing that with every new message.I think you need to sit down and re-read this thread (at least up to post #4).
function ceil_log2 (Arg : positive) return natural is
variable RetVal: natural;
begin
RetVal := log2(Arg);
if (Arg > (2**RetVal)) then
return(RetVal + 1); -- RetVal is too small, so bump it up by 1 and return
else
return(RetVal); -- Just right
end if;
end function ceil_log2;
ceil ( log2 ( real ( x ) ) ) -- uses the math.real log2 function
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?