Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register Log in

conversion of sfixed values

Status
Not open for further replies.

nesta

Junior Member level 2
Joined
Feb 19, 2010
Messages
20
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,466
Hi VhdlExperts,

I am not finding ways to typecast/ at least convert between the following (fixed point values) sfixed values.

Plz suggest.


signal Ain : sfixed(3 downto -4);

signal Bin : sfixed(7 downto -8 );

Ain <= to_sfixed(Bin,Ain) -- something like this.

Thanks in advance,
Nesta
 

TrickyDicky

Advanced Member level 5
Joined
Jun 7, 2010
Messages
7,045
Helped
2,069
Reputation
4,155
Reaction score
2,023
Trophy points
1,393
Activity points
38,827
there is no need to typecast, because they are already the same type. The to_sfixed is a conversion function used to change the type.
Being pedantic, typecasting is only possible in VHDL between similar types - arrays of the same base type. So you can do type conversions such as these examples:

signal a : std_logic_vector(7 downto 0);
signal b : unsigned(7 downto 0);
signal c : signed(7 downto 0);
signal d : ufixed(3 downto -4);
signal e : sfixed(1 downto -6);

you can cast between any of these types, because, they are all arrays of std_logic, and they are all the same length. So any of these are valid VHDL

a <= std_logic_vector(b);
e <= sfixed(a);
d <= ufixed(b);
b <= unsigned(d);
c <= signed(a);

This does a literal bit-bit transfer, so in the cases of the sfixed and ufixed the bit positions now may not mean what they did before (in real hardware, as everything is just a load of bits, there is no problem with this). But arithmetically it may be a problem. This is where type conversion functions may be used to convert types AND shift bits to maintain their meaning.

Now, in your case, all you are doing is trying to assign a number with a large range to a number with a smaller range. This is going to cause several issues:

1. Do you want overflow or saturation for Bin that are outside the range of Ain?
1. Do you want to round your numbers to the nearest or floor the result?

The simplest conversion would be just this:
Ain <= Bin(Ain'range); --this is like saying Ain <= Bin(3 downto -4);

This is going to overflow and floor the value.

To get around this, you can either manually add saturation logic:

Code:
if Bin >= 2**(Ain'high-1) then
  Ain <= x"7F";   --Saturate to  MAX

elsif Bin < -2**(Ain'high-1) then
  Ain <= x"80"; --Saturate to MIN

else
  Ain <= Bin(Ain'range);
end if;
Ill let you work out the rounding logic.

Alternatively, you can use the resize function that has the options for saturate and rounding as options:

Ain <= resize(Bin, Ain); --has two more options for rounding and saturate, which default to fixed_round and fixed_saturate

But these will not pipeline. If you need to pipeline the rounding and saturation for better performance, you will have to do it by hand.
 

nesta

Junior Member level 2
Joined
Feb 19, 2010
Messages
20
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,466
Thanks TrickyDicky for such an excellent explanation, Its very useful.

I was using the scalb function to do the conversion will that cause any issues. i dont mind truncating the fractional part though after processing.

Ain <= scalb(Bin,2)
 

TrickyDicky

Advanced Member level 5
Joined
Jun 7, 2010
Messages
7,045
Helped
2,069
Reputation
4,155
Reaction score
2,023
Trophy points
1,393
Activity points
38,827
using the scalb function, Ain and Bin must have the same width.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top