Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com 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.

Use of divide gives wrong results in VHDL

Status
Not open for further replies.

jdh_1984

Member level 2
Joined
Aug 11, 2010
Messages
52
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Norway
Activity points
1,854
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)
d:(n=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;
 

Is it RTL or gate level simulation that is failing? If its the latter, Im not surprised, due to the lack of consideration taken to hardware design.

I notice the signal f isnt big enough to store the extremes of a*e. Are you sure this isnt your problem? for example, when n is 3, a is 40320. When y is close to to the bias, x is close 1, which means a*e cannot fit into f (because with 12 bits of integer, the max you can store is 8192 + just less than 1).

You havent actually said what the problem is or how wrong the values are. Are you sure you are waiting enough clocks before you check the results?
 

In this kind of cases you can write a test code. Just write a program with inputs f and d and output dividebuffer.
The code needs to contain only one line:
dividebuffer<=f/d;

See if its working as expected. If yes, then the division operator is working fine.
 

Is it RTL or gate level simulation that is failing? If its the latter, Im not surprised, due to the lack of consideration taken to hardware design.

I notice the signal f isnt big enough to store the extremes of a*e. Are you sure this isnt your problem? for example, when n is 3, a is 40320. When y is close to to the bias, x is close 1, which means a*e cannot fit into f (because with 12 bits of integer, the max you can store is 8192 + just less than 1).

You havent actually said what the problem is or how wrong the values are. Are you sure you are waiting enough clocks before you check the results?

Hi

You have a good point with the size of f, which is to small when x is around 1. In my (functional) simulation I am using y=1, which gives x=0.6305 and a max f = 634 (for n=4). So in this case it should be big enough. But I have to change it so f could fit all values of x.
In the simulation I get repeating patterns of the dividebuffer(f/d) signal(after 130ns), so I think it should be enough clock cycles in the simulation.
The problem is the values of dividing (f/d) in the simulation, f and d are showing ok values in the simulation:
-The calculated values:
(n=1 => 0.0417, n=2 => 7.468E-03, n=3=>1.7678E-03,n=4 => 4.7822E-4)

-The simulated values:
(n=1 => 2.1457E-5, n=2 => 52.5, n=3 => 1.5655E-3, n=4 => 1.4822E-4)

The attachments are showing the simulation results (of dividebuffer=f/d).
 

Attachments

  • SimuleringTest4.jpg
    SimuleringTest4.jpg
    156.8 KB · Views: 88
  • SimuleringTest5.jpg
    SimuleringTest5.jpg
    155.6 KB · Views: 96

I think I can see what the problem is.
I think its because you're trying to use signals like variables. You have to remember, that when you do this inside a clocked process:

a <= b;
c <= a;

c will be assigned the OLD value of a, because signals do not update until the process suspends. You probably want to update half of your signals with variables inside the process.

If you ran your simulation for longer, you might get better results.

PS. What simulator are you using. Is that the ISE simulator?
 
I think I can see what the problem is.
I think its because you're trying to use signals like variables. You have to remember, that when you do this inside a clocked process:

a <= b;
c <= a;

c will be assigned the OLD value of a, because signals do not update until the process suspends. You probably want to update half of your signals with variables inside the process.

If you ran your simulation for longer, you might get better results.

PS. What simulator are you using. Is that the ISE simulator?

Thx, for giving me the “key” to solve my problem. I was not award of the variable type in VHDL ,and therefore threaded signals like variables as you highlighted. With use of variable inside the process the problem was fixed (but I got a new problem, it seems like the maclaurin series isn't accurate enough to give a good approximation to the arccos(x) with only use of four terms).

The simulator I am using is the simulator inside the Alteras quartus software (I don't know its name, I am a newbie to both VHDL and quartus)
 

The altera simulator can only do post place and route simulation, which may also be causing you problems due to weaknesses in your design. Timing problems can also show their head with this simulation.

You really need to do RTL simulation first, and to do that you need something like Modelsim - a version of which altera provide for free. RTL simulation is just a functional simulation and wont be dogged by timing problems.
 

The altera simulator can only do post place and route simulation, which may also be causing you problems due to weaknesses in your design. Timing problems can also show their head with this simulation.

You really need to do RTL simulation first, and to do that you need something like Modelsim - a version of which altera provide for free. RTL simulation is just a functional simulation and wont be dogged by timing problems.

Does Modelsim support use of fixed point? I am currently using Modelsim 6.5b, but get error when I tries to compile my design.

The error:
vcom -work work -2002 -explicit {E:/Skole/HIT/Hovedoppgave/Altera/Hjul enkoder/hjulenkodernxt.vhd}
Model Technology ModelSim ALTERA vcom 6.5b Compiler 2009.10 Oct 1 2009
-- Loading package standard
-- Loading package std_logic_1164
-- Loading package numeric_std
** Error: E:/Skole/HIT/Hovedoppgave/Altera/Hjul enkoder/hjulenkodernxt.vhd(4): Library ieee_proposed not found.
** Error: E:/Skole/HIT/Hovedoppgave/Altera/Hjul enkoder/hjulenkodernxt.vhd(5): (vcom-1136) Unknown identifier "ieee_proposed".
** Error: E:/Skole/HIT/Hovedoppgave/Altera/Hjul enkoder/hjulenkodernxt.vhd(7): VHDL Compiler exiting
 

Does Modelsim support use of fixed point?
It's no Modelsim problem, the libraries are just VHDL code. Apparently you didn't import the libraries to the simulation project.
The altera simulator can only do post place and route simulation.
Not quite right. The internal Quartus simulator (available up to V9.1) supports also functional simulation.
 

yes it does support fixed point, but in the library floatfixlib. IEEE_proposed is a temporary library.

If it doesnt have the float fixed libraries, you can add them yourself to modelsim
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top