# conversion of sfixed values

Status
Not open for further replies.

#### nesta

##### Junior Member level 2
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.

Nesta

#### TrickyDicky

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
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)