Contact me for VHDL projects or assignments

Monday, March 29, 2010

Fixed Point Operations in VHDL : Tutorial Series Part 3

     This article is a continuation of the tutorial series on fixed_pkg library.In this article I will talk about,arithmetical operations on fixed point signals.I assume that you have read Part 1 and Part 2 of the series.

     If you have gone through Part 2 of the series then you must have seen that assigning a signal results in rounding off the value if the range of the output signal is not sufficient.Yes,this is a great advantage of fixed_pkg.It is designed so that there is no possibility of an overflow.This is different from "numeric_std" library which simply neglect the underflow and overflow bits.In order to make sure that overflow doesn't happen we have to carefully design the size of output signals based on input signal size and the operation performed.The following table shows the Results range for different kind of operations:


    In the table A'left means the left most array index and A'right means the right most array index.The functions max and min are defined as follows:

max(a,b) = a if a > b else b.
min(a,b) = a if a < b else b.

The operations supported by the package for unsigned types are:
+, –, *, /, rem, mod, =, /=, <, >, >=, <=, sll, srl, rol, ror, sla, sra.

The operations supported by the package for signed types are:
+, –, *, /, rem, mod, =, /=, <, >, >=, <=, sll, srl, rol, ror, sla, sra, abs, - (unary).

 Without going much into the explanations I will directly explain their use with the help of some examples. 

Examples for addition:
signal n1,n2 : ufixed(4 downto -3);
signal n3 : ufixed(5 downto -3);
begin
n1 <=  to_ufixed (5.75,n1);     -- n1 = "00101110" = 5.75
n2 <=  to_ufixed (6.5,n2);      -- n2 = "00110100" = 6.5
n3 <= n1+n2;                   -- n3 = "001100010" = 12.25
--See that the range of 'n3' is 5 downto -3 but that of 'n1' and 'n2' is 4 downto -3.

If the range of n3 is 4 downto -3 then the result will be:
n3 = "00110001" = 6.125.
So it is very important to declare the output signal ranges as per the above table.

--For signed numbers:
signal s1,s2 : sfixed(4 downto -3);
signal s3 : sfixed(5 downto -3);
s1 <=  to_sfixed (5.75,s1);     -- s1 = "00101110" = 5.75
s2 <=  to_sfixed (-6.5,s2);     -- s2 = "11001100" = -6.5
s3 <= s1+s2;                   -- s3 = "111111010" = -0.75

Examples for Subtraction:
n1 <=  to_ufixed (5.75,n1);      -- n1 = "00101110" = 5.75
n2 <=  to_ufixed (6.5,n2);       -- n2 = "00110100" = 6.5
n3 <= n2-n1;                    -- n3 = "000000110" = 0.75    

s1 <=  to_sfixed (5.75,s1);      -- s1 = "00101110" = 5.75
s2 <=  to_sfixed (-6.5,s2);      -- s2 = "11001100" = -6.5
s3 <= s2-s1;                    -- s3 = "110011110" = -12.25

Examples for multiplication:
signal n1,n2 : ufixed(4 downto -3);
signal n3 : ufixed(9 downto -6);

signal s1,s2,s3 : sfixed(4 downto -3);
signal s4,s5 : sfixed(9 downto -6);

n1 <=  to_ufixed (5.75,n1);         -- n1 = "00101110" = 5.75
n2 <=  to_ufixed (6.5,n2);          -- n2 = "00110100" = 6.5
n3 <= n2*n1;                        -- n3 = "0000100101011000" = 37.375

s1 <=  to_sfixed (5.75,s1);         -- s1 = "00101110" = 5.75
s2 <=  to_sfixed (-6.5,s2);         -- s2 = "11001100" = -6.5
s4 <= s2*s1;                        -- s4 = "1111011010101000" = -37.375

s3 <=  to_sfixed (-5.75,s1);        -- s3 = "11010010" = -5.75
s5 <= s3*s2;                        -- s5 = "0000100101011000" = 37.375

Examples for Remainder:
signal n1 : ufixed(4 downto -3);
signal n2 : ufixed(2 downto -4);
signal n3 : ufixed(2 downto -3);     -- see how range of n3 is declared here.

signal s1 : sfixed(4 downto -3);
signal s2 : sfixed(2 downto -4);
signal s3 : sfixed(2 downto -3);     -- see how range of s3 is declared here.

n1 <=  to_ufixed (7.25,n1);        -- n1 = "00111010" = 7.25
n2 <=  to_ufixed (1.5,n2);         -- n2 = "0011000" = 1.5
n3 <= n1 rem n2;                   -- n3 = "001010" = 1.25

s1 <=  to_sfixed (-7.25,s1);       -- s1 = "11000110" = -7.25
s2 <=  to_sfixed (-1.5,s2);        -- s2 = "1101000" = -1.5
s3 <= s1 rem s2;                   -- s3 = "110110" = -1.25


Examples for division:
signal n1 : ufixed(4 downto -3);
signal n2 : ufixed(2 downto -4);
signal n3 : ufixed(8 downto -6);     -- see how range of n3 is declared here.

signal s1 : sfixed(4 downto -3);
signal s2 : sfixed(2 downto -4);
signal s3 : sfixed(9 downto -5);     -- see how range of s3 is declared here.

n1 <=  to_ufixed (6.75,n1);          -- n1 = "00110110" = 6.75
n2 <=  to_ufixed (1.5,n2);           -- n2 = "0011000" = 1.5
n3 <= n1 / n2;                       -- n3 = "000000100100000" = 1.5

s1 <=  to_sfixed (-6.75,s1);         -- s1 = "11001010" = -6.75
s2 <=  to_sfixed (1.5,s2);           -- s2 = "0011000" = 1.5
s3 <= s1 / s2;                       -- s3 = "111111101110000" = -1.5

     These are only a few of the operators available in the package.In the next part of the tutorial, I will explain the use of some more operators with example.
Read Part 1 and Part 2 of the series here:
Fixed Point Operations in VHDL : Tutorial Series Part 1
Fixed Point Operations in VHDL : Tutorial Series Part 2

5 comments:

  1. This tutorial was inspired from fixed_pkg" documentation by David Bishop.The original document can be downloaded from
    http://www.vhdl.org/fphdl/Fixed_ug.pdf

    ReplyDelete
  2. how to implement qr decomposition matrix method in vhdl

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. When I try to execute de division I get the error, Found 0 definitions for operator "/".?

    How can I solve it?

    Thanks in advance

    ReplyDelete
  5. the result of devision is 4.5
    thank you

    ReplyDelete

Related Posts with Thumbnails

Download this article as PDF