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: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.
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
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
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
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
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
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
This tutorial was inspired from fixed_pkg" documentation by David Bishop.The original document can be downloaded from
ReplyDeletehttp://www.vhdl.org/fphdl/Fixed_ug.pdf
how to implement qr decomposition matrix method in vhdl
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteWhen I try to execute de division I get the error, Found 0 definitions for operator "/".?
ReplyDeleteHow can I solve it?
Thanks in advance
the result of devision is 4.5
ReplyDeletethank you