Continue to Site

Welcome to

Welcome to our site! is an international Electronics 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.

conversion of sfixed values

Not open for further replies.


Junior Member level 2
Feb 19, 2010
Reaction score
Trophy points
Activity points
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,

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:

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

  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.

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)

using the scalb function, Ain and Bin must have the same width.

Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to