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.

Unusual bug in integration VHDL / feedback on component?

Status
Not open for further replies.

kureigu

Member level 2
Member level 2
Joined
Jan 14, 2013
Messages
49
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Scotland
Visit site
Activity points
1,779
Hey all,

I've identified a bug in an discrete integration component that I have written to determine the absolute angle from a gyroscope's movement.

What I've noticed, is that very sporadically, when I move the gyroscope too much I notice a huge and incorrect jump in value of the 'angle'. The 'angle' output is a hex value displayed on a 4x7segment display, and I've see it jump from 6FFF to CFFF with only the slightest movement. The largest output from the gyro can be 7FF, and even integrating over 4 samples it shouldn't ever have enough magnitude to create that jump which leads me to believe my integration is buggy.

I'd really appreciate if someone could look over this component and let me know if they spot anything, and even possible ways I could improve it. I'm still new-ish to VHDL and I don't have anyone giving me feedback on it at all right now, but I feel like I could improve faster if I had some.

Code:
-- Discrete integration of n samples

library ieee;

use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity time_avg is
	generic(	num_samples: integer := 4;
				auto_configure: std_logic := '1'
				);
	port(	new_data: in std_logic;
			sample: in unsigned(11 downto 0);
			manual_zero: in unsigned(11 downto 0);
			integral: out unsigned(15 downto 0)
			);
end time_avg;

architecture integrate of time_avg is
	
	--type array_type is array(0 to num_samples-1) of unsigned(11 downto 0);
	--signal sample_buffer: array_type;
	signal sum: unsigned (15 downto 0) := X"7FFF";
	signal count: integer := 0;
	signal zero_sampled: std_logic := '0';
	signal zero, first_zero: unsigned(11 downto 0);
	
begin

	process(sample, new_data)
	begin
		-- When new data becomes available..
		if rising_edge(new_data) then
		
			if(zero_sampled = '0') then
				first_zero <= sample;
				zero_sampled <= '1';
			end if;
			
			if(auto_configure = '1') then
				zero <= first_zero;
			else
				zero <= manual_zero;
			end if;
	
			sum <= sum + sample - zero;
			count <= count+1;
			
			if count > num_samples-1 then
				integral <= sum;
				count <= 0;
			end if;
			
		end if;
		
	end process;

end integrate;

The new data flag is raised every time data is received via SPI from an ADC attached to the gyroscope. It's 11 bits so its max is limited to 0x7FF.
 

The best way to improve it would be to make it synchronous (ie. use a system clock) rather than use a "new data" flag as a clock.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top