jdh_1984
Member level 2
Hi
I am trying to code a VHDL program that uses the Mclaurin series to calculate the value of arccos(x). I have simulated the code but the line dividebuffer<=f/d; gives wrong values. I have tracked the Signals f and d and this are ok (uses a input y=1 (decimal)).
The tracked values :
f: (n=1 => 0.5008, n=2 => 2.39, n=3 => 28.47, n=4 => 630)
dn=1 => 12, n=2 => 320, n=3 => 16128, n=4 => 1327104)
f/d should give the values( but are not):
(n=1 => 0.0417, n=2 => 7.468E-03, n=3=>1.7678E-03,n=4 => 4.7822E-4)
The code:
Library ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library ieee_proposed;
use ieee_proposed.fixed_pkg.all;
ENTITY Test IS
PORT(
y : IN sfixed(7 downto -4); --Readed accelerometer value
Clock : IN STD_LOGIC;
alphaEstOut : OUT ufixed(8 downto -12)); --Outputed accelerometer value (rad)
END Test;
ARCHITECTURE Behavior OF Test IS
SIGNAL Pihalf : sfixed(3 downto -5);
SIGNAL Factorial,Factorialbuff: sfixed(7 downto -12);
SIGNAL nSfixed : sfixed(5 downto 0);
SIGNAL n : SIGNED(3 downto 0);
SIGNAL x : sfixed(7 downto -12);
SIGNAL bias : sfixed(7 downto -12);
SIGNAL binit,b,c,e : sfixed(7 downto -12);
SIGNAL alphaEst : sfixed(7 downto -12);
SIGNAL a : sfixed(16 downto 0);
SIGNAL aa : sfixed(alphaEst'high +1 downto alphaEst'low);
SIGNAL d : sfixed(21 downto 0);
SIGNAL f : sfixed(12 downto -10);
SIGNAL dividebuffer : sfixed(13 downto -31);
SIGNAL subBuffer1 : sfixed(8 downto -12);
SIGNAL subBuffer2 : sfixed(14 downto -31);
BEGIN
bias<=to_sfixed(1.586,bias);--fixed bias =1.586V
Pihalf<=to_sfixed(1.5707,Pihalf); --Pi = 3.1415....
PROCESS(y,Clock)--Start processing when a new value enters y-pins
BEGIN
IF rising_edge(Clock) THEN
IF (n="0000") THEN
--Calculate the argument for the arccos function
IF (y>=bias)THEN
x<=resize(bias/y,x);
ELSIF (y<bias) THEN
x<=resize(y/bias,x);
END IF;
--Factorial 0!=1
Factorial<=to_sfixed(1.0,Factorial); --Initial value;
binit<=to_sfixed(4,binit); --Initial value;
b<=to_sfixed(1,b);
subBuffer1<=Pihalf-x; --Initial value;
alphaEst<=resize(subBuffer1,alphaEst); --for term n=0 in Taylor series (Pi/2-n0)
n<="0001";
ELSIF (n>"0000" AND n<="0100")THEN
nSfixed<=to_sfixed(n,nSfixed);
--Factorial 1!,2!,3!,4!
--Factorial<=resize(Factorial*nSfixed,Factorial);--Factorial,n=1=>1,n=2=>2,n=3=>6, n=4=>24
--b<=resize(b*binit,b); --For use in the Taylor series calculation
--c<=resize(2*nSfixed+1,c); --For use in the Taylor series calculation
--d<=resize(b*Factorial*Factorial*c,d); --For use in the Taylor series calculation
Case n IS --For use in the Taylor series calculation
WHEN "0000"=>
e<=e;
WHEN "0001"=>
a<=to_sfixed(2,a);
e<=resize(x*x*x,e);
d<=to_sfixed(12,d);
WHEN "0010"=>
a<=to_sfixed(24,a);
e<=resize(x*x*x*x*x,e);
d<=to_sfixed(320,d);
WHEN "0011"=>
a<=to_sfixed(720,a);
e<=resize(x*x*x*x*x*x*x,e);
d<=to_sfixed(16128,d);
WHEN "0100"=>
a<=to_sfixed(40320,a);
e<=resize(x*x*x*x*x*x*x*x*x,e);
d<=to_sfixed(1327104,d);
WHEN "0101"=>
e<=resize(x*x*x*x*x*x*x*x*x*x*x,e);
WHEN "0110"=>
e<=e;
WHEN "0111"=>
e<=e;
WHEN "1000"=>
e<=e;
WHEN "1001"=>
e<=e;
WHEN "1010"=>
e<=e;
WHEN "1011"=>
e<=e;
WHEN "1100"=>
e<=e;
WHEN "1101"=>
e<=e;
WHEN "1110"=>
e<=e;
WHEN "1111"=>
e<=e;
END CASE;
f<=resize(a*e,f); --For use in the Taylor series calculation
dividebuffer<=f/d;
subBuffer2<=alphaEst - dividebuffer;
alphaEst<=resize(subBuffer2,alphaEst);
n<=n+1;
ELSIF (n>="0101") THEN
n<="0000";
--Outputting the result
aa<=abs(alphaEst);
alphaEstOut<=ufixed(aa);
alphaEst<=to_sfixed(0,alphaEst);
END IF;
END IF;
END PROCESS;
END Behavior;
I am trying to code a VHDL program that uses the Mclaurin series to calculate the value of arccos(x). I have simulated the code but the line dividebuffer<=f/d; gives wrong values. I have tracked the Signals f and d and this are ok (uses a input y=1 (decimal)).
The tracked values :
f: (n=1 => 0.5008, n=2 => 2.39, n=3 => 28.47, n=4 => 630)
dn=1 => 12, n=2 => 320, n=3 => 16128, n=4 => 1327104)
f/d should give the values( but are not):
(n=1 => 0.0417, n=2 => 7.468E-03, n=3=>1.7678E-03,n=4 => 4.7822E-4)
The code:
Library ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library ieee_proposed;
use ieee_proposed.fixed_pkg.all;
ENTITY Test IS
PORT(
y : IN sfixed(7 downto -4); --Readed accelerometer value
Clock : IN STD_LOGIC;
alphaEstOut : OUT ufixed(8 downto -12)); --Outputed accelerometer value (rad)
END Test;
ARCHITECTURE Behavior OF Test IS
SIGNAL Pihalf : sfixed(3 downto -5);
SIGNAL Factorial,Factorialbuff: sfixed(7 downto -12);
SIGNAL nSfixed : sfixed(5 downto 0);
SIGNAL n : SIGNED(3 downto 0);
SIGNAL x : sfixed(7 downto -12);
SIGNAL bias : sfixed(7 downto -12);
SIGNAL binit,b,c,e : sfixed(7 downto -12);
SIGNAL alphaEst : sfixed(7 downto -12);
SIGNAL a : sfixed(16 downto 0);
SIGNAL aa : sfixed(alphaEst'high +1 downto alphaEst'low);
SIGNAL d : sfixed(21 downto 0);
SIGNAL f : sfixed(12 downto -10);
SIGNAL dividebuffer : sfixed(13 downto -31);
SIGNAL subBuffer1 : sfixed(8 downto -12);
SIGNAL subBuffer2 : sfixed(14 downto -31);
BEGIN
bias<=to_sfixed(1.586,bias);--fixed bias =1.586V
Pihalf<=to_sfixed(1.5707,Pihalf); --Pi = 3.1415....
PROCESS(y,Clock)--Start processing when a new value enters y-pins
BEGIN
IF rising_edge(Clock) THEN
IF (n="0000") THEN
--Calculate the argument for the arccos function
IF (y>=bias)THEN
x<=resize(bias/y,x);
ELSIF (y<bias) THEN
x<=resize(y/bias,x);
END IF;
--Factorial 0!=1
Factorial<=to_sfixed(1.0,Factorial); --Initial value;
binit<=to_sfixed(4,binit); --Initial value;
b<=to_sfixed(1,b);
subBuffer1<=Pihalf-x; --Initial value;
alphaEst<=resize(subBuffer1,alphaEst); --for term n=0 in Taylor series (Pi/2-n0)
n<="0001";
ELSIF (n>"0000" AND n<="0100")THEN
nSfixed<=to_sfixed(n,nSfixed);
--Factorial 1!,2!,3!,4!
--Factorial<=resize(Factorial*nSfixed,Factorial);--Factorial,n=1=>1,n=2=>2,n=3=>6, n=4=>24
--b<=resize(b*binit,b); --For use in the Taylor series calculation
--c<=resize(2*nSfixed+1,c); --For use in the Taylor series calculation
--d<=resize(b*Factorial*Factorial*c,d); --For use in the Taylor series calculation
Case n IS --For use in the Taylor series calculation
WHEN "0000"=>
e<=e;
WHEN "0001"=>
a<=to_sfixed(2,a);
e<=resize(x*x*x,e);
d<=to_sfixed(12,d);
WHEN "0010"=>
a<=to_sfixed(24,a);
e<=resize(x*x*x*x*x,e);
d<=to_sfixed(320,d);
WHEN "0011"=>
a<=to_sfixed(720,a);
e<=resize(x*x*x*x*x*x*x,e);
d<=to_sfixed(16128,d);
WHEN "0100"=>
a<=to_sfixed(40320,a);
e<=resize(x*x*x*x*x*x*x*x*x,e);
d<=to_sfixed(1327104,d);
WHEN "0101"=>
e<=resize(x*x*x*x*x*x*x*x*x*x*x,e);
WHEN "0110"=>
e<=e;
WHEN "0111"=>
e<=e;
WHEN "1000"=>
e<=e;
WHEN "1001"=>
e<=e;
WHEN "1010"=>
e<=e;
WHEN "1011"=>
e<=e;
WHEN "1100"=>
e<=e;
WHEN "1101"=>
e<=e;
WHEN "1110"=>
e<=e;
WHEN "1111"=>
e<=e;
END CASE;
f<=resize(a*e,f); --For use in the Taylor series calculation
dividebuffer<=f/d;
subBuffer2<=alphaEst - dividebuffer;
alphaEst<=resize(subBuffer2,alphaEst);
n<=n+1;
ELSIF (n>="0101") THEN
n<="0000";
--Outputting the result
aa<=abs(alphaEst);
alphaEstOut<=ufixed(aa);
alphaEst<=to_sfixed(0,alphaEst);
END IF;
END IF;
END PROCESS;
END Behavior;