--Frequency Table Counter logic
--By Colin O'Flynn, coflynn@newae.com
--website: www.newae.com
--Revision: 20040320
--This module is designed to take a streaming parallel input data and count how many times each number has occured,
--then can return which numbers occured the most. Each data byte is actually a colour, so this module is designed
--to figure out the most prevelent colour in an area

--Designed to work with TVP5145 from Texas Instruments, see its datasheet for diagrams of the clock. The clocks are:
--PCLK: dataclk_in, SCLK: dbldataclk_in, PREF: dataclk90_in

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

package freq_table is

--This component is the one that can get the most common colour
component frequency_table is
    Port (
 		 reset_in			: in std_logic; --when active high resets everything to 0  
		 reset_out		: out std_logic; --line goes high when reset is complete, goes low when reset_in goes low
		 							  --you MUST make sure reset_in goes low only after this line goes high!!  

    		 dataclk_in 		: in std_logic; --data is set-up on falling edge of this clock
    		 dbldataclk_in 	: in std_logic; --clock runs at twice frequency of dataclk_in, data at data_in MUST be ready
    		 				--by the rising edge of this clock after the falling edge of
    		 				--dataclk_in
    		 dataclk90_in		: in std_logic; --dataclk_in, but shifted 90 degrees (1/4 wave length) so that
    		 				--when falling edge of dataclk_in comes, dataclk90_in is high
    		 
		 data_in 			: in std_logic_vector(7 downto 0); --the data in. If the system is in the record mode and
		 							 --data_rdy_in is active ('1') then every rising clock on dataclk_in will
									 --result in the count for the number of times 'data' has appeared to increase
									 --by one
		 data_rdy_in		: in std_logic; --active high - when high will work as described above
		 record_in		: in std_logic; --when active ('1') module will record the data that is comming though
		 							 --on falling edge module will start to generate a list of the data that
									 --has occured the most and output it
	      lowerlimit_in 	: in std_logic_vector(7 downto 0); --if data_in is below this value it will be ignored
		 upperlimit_in		: in std_logic_vector(7 downto 0); --if data_in is above this value it will be ignored

		 data_rdy_out		: out std_logic; --after record_in going low, this will go high when data can finally be read
		 sort_addr_in		: in std_logic_vector(2 downto 0); --select the most occuring colour - 0 is occurs most, 7 is
		 											--occurs 8th most
		 data_out			: out std_logic_vector(7 downto 0); --the data value that occured the nth amount
		 datacount_out		: out std_logic_vector(11 downto 0) --how many times the data value occured
		);
end component frequency_table;

--This component is stripped of the sort logic, so it is JUST a frequency table.
component frequency_table_nosort is
	Port (
 		 reset_in			: in std_logic; --when active high resets everything to 0  
		 reset_out		: out std_logic; --line goes high when reset is complete, goes low when reset_in goes low
		 							  --you MUST make sure reset_in goes low only after this line goes high!!  

    		 dataclk_in 		: in std_logic; --data is set-up on falling edge of this clock
    		 dbldataclk_in 	: in std_logic; --clock runs at twice frequency of dataclk_in, data at data_in MUST be ready
    		 				--by the rising edge of this clock after the falling edge of
    		 				--dataclk_in
    		 dataclk90_in		: in std_logic; --dataclk_in, but shifted 90 degrees (1/4 wave length) so that
    		 				--when falling edge of dataclk_in comes, dataclk90_in is high
    		 
		 data_in 			: in std_logic_vector(7 downto 0); --the data in. If the system is in the record mode and
		 							 --data_rdy_in is active ('1') then every rising clock on dataclk_in will
									 --result in the count for the number of times 'data' has appeared to increase
									 --by one
		 data_rdy_in		: in std_logic; --active high - when high will work as described above

		 datacount_out		: out std_logic_vector(11 downto 0) --how many times the data value occured, this is outputted
		 											 --on the first rising edge of dbldataclk_in after the falling
													 --edge of dataclk_in, but should not be red to the falling edge
													 --after that
		);
end component frequency_table_nosort;
	
end package freq_table;


----------------------------------------------------------------------------------------------------------------
--- Frequency Table WIT sort algorithm -------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity frequency_table is
    Port ( 
		 reset_in			: in std_logic; --when active high resets everything to 0  
		 reset_out		: out std_logic; --line goes high when reset is complete, goes low when reset_in goes low
		 							  --you MUST make sure reset_in goes low only after this line goes high!!  

    		 dataclk_in 		: in std_logic; --data is set-up on falling edge of this clock
    		 dbldataclk_in 	: in std_logic; --clock runs at twice frequency of dataclk_in, data at data_in MUST be ready
    		 				--by the rising edge of this clock after the falling edge of
    		 				--dataclk_in
    		 dataclk90_in		: in std_logic; --dataclk_in, but shifted 90 degrees (1/4 wave length) so that
    		 				--when falling edge of dataclk_in comes, dataclk90_in is high
    		           
		 data_in 			: in std_logic_vector(7 downto 0); --the data in. If the system is in the record mode and
		 							 --data_rdy_in is active ('1') then every rising clock on dataclk_in will
									 --result in the count for the number of times 'data' has appeared to increase
									 --by one
		 data_rdy_in		: in std_logic; --active high - when high will work as described above
		 record_in		: in std_logic; --when active ('1') module will record the data that is comming though
		 							 --on falling edge module will start to generate a list of the data that
									 --has occured the most and output it
	      lowerlimit_in 	: in std_logic_vector(7 downto 0); --if data_in is below this value it will be ignored
		 upperlimit_in		: in std_logic_vector(7 downto 0); --if data_in is above this value it will be ignored

		 data_rdy_out		: out std_logic; --after record_in going low, this will go high when data can finally be read
		 sort_addr_in		: in std_logic_vector(2 downto 0); --select the most occuring colour - 0 is occurs most, 7 is
		 											--occurs 8th most
		 data_out			: out std_logic_vector(7 downto 0); --the data value that occured the nth amount
		 datacount_out		: out std_logic_vector(11 downto 0) --how many times the data value occured			
		 );
end frequency_table;


architecture Behavioral of frequency_table is

   --RAM, 12 bits x 256
   --rising edge clock latches address
   component freqtable_ramcomp
	port (
	addr: IN std_logic_VECTOR(7 downto 0);
	clk: IN std_logic;
	din: IN std_logic_VECTOR(11 downto 0);
	dout: OUT std_logic_VECTOR(11 downto 0);
	we: IN std_logic);
   end component;
   
   signal rw_data 			: std_logic; --RW line, when high the ram will be in write mode
   signal colour_count_in, colour_count_out : std_logic_vector (11 downto 0);
   signal colour_count_cntr 	: std_logic_vector (11 downto 0);

   signal ram_clk			: std_logic; --rising edge active ram clock
   signal ram_addr			: std_logic_vector (7 downto 0); --ram address

   signal wr_ramstatus  : std_logic;
   

   signal sort_addr		 	: std_logic_vector (7 downto 0);

   --blockram doesn't support 3 bit address, so make our own ram with arrays...
   type sorttable_ram1_type is array (7 downto 0) of std_logic_vector (7 downto 0);
   type sorttable_ram2_type is array (7 downto 0) of std_logic_vector (11 downto 0);
   signal sorttable_ram_colour: sorttable_ram1_type;
   signal sorttable_ram_count	: sorttable_ram2_type;
 
   signal sortram_colour_out	: std_logic_vector (7 downto 0);
   signal sortram_count_out	: std_logic_vector (11 downto 0);   
   signal sortram_addr		: std_logic_vector (2 downto 0);
   signal sort_done			: std_logic;

   signal reset_addr		: std_logic_vector (7 downto 0);
   constant addr_incr 		: std_logic_vector (7 downto 0) := "00000001";
   constant addr_max  		: std_logic_vector (7 downto 0) := "11111111";

   type core_state_type is (reset, rec, sort);
   signal core_state: core_state_type;


begin

   RAMIMAGE1:  freqtable_ramcomp port map(
	addr => ram_addr,
	clk => ram_clk,
	din => colour_count_in,
	dout => colour_count_out,
	we => rw_data
	);


	--when we are reseting unit set count of data to 0, otherwise set to increment
	colour_count_in <= (others => '0') when core_state = reset else colour_count_cntr;

	--when resetting unit always stay in write mode
	--since the reset logic writes every address to 0
	--or if wr_ramstatus is high and we want to record the data, and the data is ready
	--otherwise goto read mode
	rw_data <= '1' when core_state = reset or ((wr_ramstatus = '1') and (record_in = '1') and (data_rdy_in = '1')) else
			 '0';

	--ram clk	, rising-edge is active edge
	ram_clk <= dbldataclk_in;

	--the ram address is controlled by reset logic when in reset, sort_addr when we
	--want to sort the data, otherwise controlled by data_in
	ram_addr <= reset_addr when core_state = reset else 
			  sort_addr when core_state = sort else
			  data_in;

	
	
	--set the 'core state' as needed
	core_state <= reset when reset_in = '1' else
			    rec   when record_in = '1' else
			    sort;


	--RECORD LOGIC
	process(dataclk_in, dbldataclk_in)
	begin
	if falling_edge(dbldataclk_in) then
		if dataclk90_in = '0' then
			wr_ramstatus <= '1';
			
		else
			wr_ramstatus <= '0';
		end if;
	end if;
	end process;

	--on the falling edge of dbldataclk_in the data_in will have been latched onto the RAM's address bus, so the
	--count value should be ready by now. We now increment the count (making sure not to overflow) and put
	--it on the input data from the RAM, so it will be written on the next rising edge of the dbldataclk_in
	process(dataclk_in, dbldataclk_in)
	begin
	if falling_edge(dbldataclk_in) then
		if dataclk90_in = '0' then
			if colour_count_out = "111111111111" then
				colour_count_cntr <= "111111111111";
			else
				--always increment the colour_count_in, unless we are at the maximum in which case don't
				colour_count_cntr <= colour_count_out + "000000000001";
			end if;
		end if;
	end if;
	end process;


	--SORT LOGIC

	sortram_addr <= sort_addr_in;

	process(core_state, sort_done, ram_clk, lowerlimit_in)
	begin

	--includes simple reset-all-sorttable-ram system
	if (core_state = reset) then
		sorttable_ram_colour(0) <= (others => '0');
		sorttable_ram_colour(1) <= (others => '0');
		sorttable_ram_colour(2) <= (others => '0');
		sorttable_ram_colour(3) <= (others => '0');
		sorttable_ram_colour(4) <= (others => '0');
		sorttable_ram_colour(5) <= (others => '0');
		sorttable_ram_colour(6) <= (others => '0');
		sorttable_ram_colour(7) <= (others => '0');

		sorttable_ram_count(0) <= (others => '0');
		sorttable_ram_count(1) <= (others => '0');
		sorttable_ram_count(2) <= (others => '0');
		sorttable_ram_count(3) <= (others => '0');
		sorttable_ram_count(4) <= (others => '0');
		sorttable_ram_count(5) <= (others => '0');
		sorttable_ram_count(6) <= (others => '0');
		sorttable_ram_count(7) <= (others => '0');

		sort_addr <= lowerlimit_in;
		sort_done <= '0';
		data_rdy_out <= '0';

     --if done sorting then we stop and set data_rdy_out to '1'
	elsif (sort_done = '1') then

		data_rdy_out <= '1';

	elsif falling_edge(ram_clk) then
	     if core_state = sort then		
		sort_addr <= sort_addr + addr_incr;

		--done sorting through once we have all 
		if (sort_addr = upperlimit_in) then
			sort_done <= '1';
		end if;

          --now we check if the current colour_count is higher than each
		--1st, 2nd, ... , 7th, 8th most occuring colour. 
		if (sorttable_ram_count(0) < colour_count_out) then

   		  --OK, check if the count increased but for the same value,
		  --in which case we just change the count
		  if (sorttable_ram_colour(0) = sort_addr) then
		  	sorttable_ram_count(0) <= colour_count_out;
		  else
		  --Now we shift all the data below the new colour down (shifting one colour
		  --off the list)
			sorttable_ram_count(7) <= sorttable_ram_count(6);
			sorttable_ram_count(6) <= sorttable_ram_count(5);
			sorttable_ram_count(5) <= sorttable_ram_count(4);
			sorttable_ram_count(4) <= sorttable_ram_count(3);
			sorttable_ram_count(3) <= sorttable_ram_count(2);
			sorttable_ram_count(2) <= sorttable_ram_count(1);
			sorttable_ram_count(1) <= sorttable_ram_count(0);
			sorttable_ram_count(0) <= colour_count_out;

			sorttable_ram_colour(7) <= sorttable_ram_colour(6);
			sorttable_ram_colour(6) <= sorttable_ram_colour(5);
			sorttable_ram_colour(5) <= sorttable_ram_colour(4);
			sorttable_ram_colour(4) <= sorttable_ram_colour(3);
			sorttable_ram_colour(3) <= sorttable_ram_colour(2);
			sorttable_ram_colour(2) <= sorttable_ram_colour(1);
			sorttable_ram_colour(1) <= sorttable_ram_colour(0);
			sorttable_ram_colour(0) <= sort_addr;
		   end if;

		elsif (sorttable_ram_count(1) < colour_count_out) then
   		  --OK, check if the count increased but for the same value,
		  --in which case we just change the count
		  if (sorttable_ram_colour(1) = sort_addr) then
		  	sorttable_ram_count(1) <= colour_count_out;
		  else
		  --Now we shift all the data below the new colour down (shifting one colour
		  --off the list)
			sorttable_ram_count(7) <= sorttable_ram_count(6);
			sorttable_ram_count(6) <= sorttable_ram_count(5);
			sorttable_ram_count(5) <= sorttable_ram_count(4);
			sorttable_ram_count(4) <= sorttable_ram_count(3);
			sorttable_ram_count(3) <= sorttable_ram_count(2);
			sorttable_ram_count(2) <= sorttable_ram_count(1);
			sorttable_ram_count(1) <= colour_count_out;

			sorttable_ram_colour(7) <= sorttable_ram_colour(6);
			sorttable_ram_colour(6) <= sorttable_ram_colour(5);
			sorttable_ram_colour(5) <= sorttable_ram_colour(4);
			sorttable_ram_colour(4) <= sorttable_ram_colour(3);
			sorttable_ram_colour(3) <= sorttable_ram_colour(2);
			sorttable_ram_colour(2) <= sorttable_ram_colour(1);
			sorttable_ram_colour(1) <= sort_addr;
            end if;

		elsif (sorttable_ram_count(2) < colour_count_out) then
   		  --OK, check if the count increased but for the same value,
		  --in which case we just change the count
		  if (sorttable_ram_colour(2) = sort_addr) then
		  	sorttable_ram_count(2) <= colour_count_out;
		  else
		  --Now we shift all the data below the new colour down (shifting one colour
		  --off the list)
			sorttable_ram_count(7) <= sorttable_ram_count(6);
			sorttable_ram_count(6) <= sorttable_ram_count(5);
			sorttable_ram_count(5) <= sorttable_ram_count(4);
			sorttable_ram_count(4) <= sorttable_ram_count(3);
			sorttable_ram_count(3) <= sorttable_ram_count(2);
			sorttable_ram_count(2) <= colour_count_out;

			sorttable_ram_colour(7) <= sorttable_ram_colour(6);
			sorttable_ram_colour(6) <= sorttable_ram_colour(5);
			sorttable_ram_colour(5) <= sorttable_ram_colour(4);
			sorttable_ram_colour(4) <= sorttable_ram_colour(3);
			sorttable_ram_colour(3) <= sorttable_ram_colour(2);
			sorttable_ram_colour(2) <= sort_addr;
   		  end if;

		elsif (sorttable_ram_count(3) < colour_count_out) then
   		  --OK, check if the count increased but for the same value,
		  --in which case we just change the count
		  if (sorttable_ram_colour(3) = sort_addr) then
		  	sorttable_ram_count(3) <= colour_count_out;
		  else
		  --Now we shift all the data below the new colour down (shifting one colour
		  --off the list)
			sorttable_ram_count(7) <= sorttable_ram_count(6);
			sorttable_ram_count(6) <= sorttable_ram_count(5);
			sorttable_ram_count(5) <= sorttable_ram_count(4);
			sorttable_ram_count(4) <= sorttable_ram_count(3);
			sorttable_ram_count(3) <= colour_count_out;

			sorttable_ram_colour(7) <= sorttable_ram_colour(6);
			sorttable_ram_colour(6) <= sorttable_ram_colour(5);
			sorttable_ram_colour(5) <= sorttable_ram_colour(4);
			sorttable_ram_colour(4) <= sorttable_ram_colour(3);
			sorttable_ram_colour(3) <= sort_addr;
		  end if;

		elsif (sorttable_ram_count(4) < colour_count_out) then
   		  --OK, check if the count increased but for the same value,
		  --in which case we just change the count
		  if (sorttable_ram_colour(4) = sort_addr) then
		  	sorttable_ram_count(4) <= colour_count_out;
		  else
		  --Now we shift all the data below the new colour down (shifting one colour
		  --off the list)
			sorttable_ram_count(7) <= sorttable_ram_count(6);
			sorttable_ram_count(6) <= sorttable_ram_count(5);
			sorttable_ram_count(5) <= sorttable_ram_count(4);
			sorttable_ram_count(4) <= colour_count_out;

			sorttable_ram_colour(7) <= sorttable_ram_colour(6);
			sorttable_ram_colour(6) <= sorttable_ram_colour(5);
			sorttable_ram_colour(5) <= sorttable_ram_colour(4);
			sorttable_ram_colour(4) <= sort_addr;
		   end if;

		elsif (sorttable_ram_count(5) < colour_count_out) then
   		  --OK, check if the count increased but for the same value,
		  --in which case we just change the count
		  if (sorttable_ram_colour(5) = sort_addr) then
		  	sorttable_ram_count(5) <= colour_count_out;
		  else
		  --Now we shift all the data below the new colour down (shifting one colour
		  --off the list)
			sorttable_ram_count(7) <= sorttable_ram_count(6);
			sorttable_ram_count(6) <= sorttable_ram_count(5);
			sorttable_ram_count(5) <= colour_count_out;

			sorttable_ram_colour(7) <= sorttable_ram_colour(6);
			sorttable_ram_colour(6) <= sorttable_ram_colour(5);
			sorttable_ram_colour(5) <=  sort_addr;
             end if;

		elsif (sorttable_ram_count(6) < colour_count_out)	then
   		  --OK, check if the count increased but for the same value,
		  --in which case we just change the count
		  if (sorttable_ram_colour(6) = sort_addr) then
		  	sorttable_ram_count(6) <= colour_count_out;
		  else
		  --Now we shift all the data below the new colour down (shifting one colour
		  --off the list)
			sorttable_ram_count(7) <= sorttable_ram_count(6);
			sorttable_ram_count(6) <= colour_count_out;

			sorttable_ram_colour(7) <= sorttable_ram_colour(6);
			sorttable_ram_colour(6) <= sort_addr;
	        end if;

		elsif (sorttable_ram_count(7) < colour_count_out)	then
   		  --OK, check if the count increased but for the same value,
		  --in which case we just change the count
		  if (sorttable_ram_colour(7) = sort_addr) then
		  	sorttable_ram_count(7) <= colour_count_out;
		  else
		  --Now we shift all the data below the new colour down (shifting one colour
		  --off the list)
			sorttable_ram_count(7) <= colour_count_out;

			sorttable_ram_colour(7) <= sort_addr;
            end if;
		end if;
	   end if;
	end if;
	end process;


	--simple multiplexor to output the data from the sorting table "RAM"
	sortram_colour_out <= 	sorttable_ram_colour(0) when sortram_addr = "000" else
						sorttable_ram_colour(1) when sortram_addr = "001" else
						sorttable_ram_colour(2) when sortram_addr = "010" else
						sorttable_ram_colour(3) when sortram_addr = "011" else
						sorttable_ram_colour(4) when sortram_addr = "100" else
						sorttable_ram_colour(5) when sortram_addr = "101" else
						sorttable_ram_colour(6) when sortram_addr = "110" else
						sorttable_ram_colour(7) when sortram_addr = "111" else
						(others => 'X');

	--simple multiplexor to output the data from the sorting table "RAM"
	sortram_count_out <= 	sorttable_ram_count(0) when sortram_addr = "000" else
						sorttable_ram_count(1) when sortram_addr = "001" else
						sorttable_ram_count(2) when sortram_addr = "010" else
						sorttable_ram_count(3) when sortram_addr = "011" else
						sorttable_ram_count(4) when sortram_addr = "100" else
						sorttable_ram_count(5) when sortram_addr = "101" else
						sorttable_ram_count(6) when sortram_addr = "110" else
						sorttable_ram_count(7) when sortram_addr = "111" else
						(others => 'X');

	data_out <= sortram_colour_out;
	datacount_out <= sortram_count_out;
		


	--RESET LOGIC
	--clears the entire storage RAM
	process(ram_clk, reset_in)
	begin
	if (reset_in = '0') then
		--reset finished, get ready for next reset

		--reset the address buffers
		--reset_addr <= (others => '0');
		reset_addr <= "00000000";
	
		--take reset_out low
		reset_out <= '0';
	--increment the ram address
	elsif rising_edge(ram_clk) then
		--check if we have cleared all ram.
	 	if (reset_addr = addr_max) then
			reset_out <= '1';
		else
			--increment address by one on falling edge of ramclk
			reset_addr <= reset_addr + addr_incr;
		end if;
	end if;
	end process;
	




end Behavioral;


----------------------------------------------------------------------------------------------------------------
--- Frequency Table WITHOUT sort algorithm ---------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity frequency_table_nosort is
    Port ( 
		 reset_in			: in std_logic; --when active high resets everything to 0  
		 reset_out		: out std_logic; --line goes high when reset is complete, goes low when reset_in goes low
		 							  --you MUST make sure reset_in goes low only after this line goes high!!  

    		 dataclk_in 		: in std_logic; --data is set-up on falling edge of this clock
    		 dbldataclk_in 	: in std_logic; --clock runs at twice frequency of dataclk_in, data at data_in MUST be ready
    		 				--by the rising edge of this clock after the falling edge of
    		 				--dataclk_in
    		 dataclk90_in		: in std_logic; --dataclk_in, but shifted 90 degrees (1/4 wave length) so that
    		 				--when falling edge of dataclk_in comes, dataclk90_in is high
    		           
		 data_in 			: in std_logic_vector(7 downto 0); --the data in. If the system is in the record mode and
		 							 --data_rdy_in is active ('1') then every rising clock on dataclk_in will
									 --result in the count for the number of times 'data' has appeared to increase
									 --by one
		 data_rdy_in		: in std_logic; --active high - when high will work as described above

		 datacount_out		: out std_logic_vector(11 downto 0) --how many times the data value occured, this is outputted
		 											 --on the first rising edge of dbldataclk_in after the falling
													 --edge of dataclk_in, but should not be red to the falling edge
													 --after that			
		 );
end frequency_table_nosort;

architecture Behavioral of frequency_table_nosort is

   --RAM, 12 bits x 256
   --rising edge clock latches address
   component freqtable_ramcomp
	port (
	addr: IN std_logic_VECTOR(7 downto 0);
	clk: IN std_logic;
	din: IN std_logic_VECTOR(11 downto 0);
	dout: OUT std_logic_VECTOR(11 downto 0);
	we: IN std_logic);
   end component;
   
   signal rw_data 			: std_logic; --RW line, when high the ram will be in write mode
   signal colour_count_in, colour_count_out : std_logic_vector (11 downto 0);
   signal colour_count_cntr 	: std_logic_vector (11 downto 0);

   signal ram_clk			: std_logic; --rising edge active ram clock
   signal ram_addr			: std_logic_vector (7 downto 0); --ram address

   signal wr_ramstatus  : std_logic;
   
   signal reset_addr		: std_logic_vector (7 downto 0);
   constant addr_incr 		: std_logic_vector (7 downto 0) := "00000001";
   constant addr_max  		: std_logic_vector (7 downto 0) := "11111111";

   type core_state_type is (reset, rec);
   signal core_state: core_state_type;


begin

   RAMIMAGE_NOSORT:  freqtable_ramcomp port map(
	addr => ram_addr,
	clk => ram_clk,
	din => colour_count_in,
	dout => colour_count_out,
	we => rw_data
	);


	--when we are reseting unit set count of data to 0, otherwise set to increment
	colour_count_in <= (others => '0') when core_state = reset else colour_count_cntr;

	--when resetting unit always stay in write mode
	--since the reset logic writes every address to 0
	--or if wr_ramstatus is high and we want to record the data, and the data is ready
	--otherwise goto read mode
	rw_data <= '1' when core_state = reset or ((wr_ramstatus = '1') and (data_rdy_in = '1')) else
			 '0';

	--ram clk	, rising-edge is active edge
	ram_clk <= dbldataclk_in;

	--the ram address is controlled by reset logic when in reset, sort_addr when we
	--want to sort the data, otherwise controlled by data_in
	ram_addr <= reset_addr when core_state = reset else 
			  data_in;

	
	
	--set the 'core state' as needed
	core_state <= reset when reset_in = '1' else
			    rec;


	--RECORD LOGIC
	process(dataclk_in, dbldataclk_in)
	begin
	if falling_edge(dbldataclk_in) then
		if dataclk90_in = '0' then
			wr_ramstatus <= '1';
			
		else
			wr_ramstatus <= '0';
		end if;
	end if;
	end process;

	--on the falling edge of dbldataclk_in the data_in will have been latched onto the RAM's address bus, so the
	--count value should be ready by now. We now increment the count (making sure not to overflow) and put
	--it on the input data from the RAM, so it will be written on the next rising edge of the dbldataclk_in
	process(dataclk_in, dbldataclk_in)
	begin
	if falling_edge(dbldataclk_in) then
		if dataclk90_in = '0' then
			if colour_count_out = "111111111111" then
				colour_count_cntr <= "111111111111";
			else
				--always increment the colour_count_in, unless we are at the maximum in which case don't
				colour_count_cntr <= colour_count_out + "000000000001";
			end if;
		end if;
	end if;
	end process;


	datacount_out <= colour_count_out;	


	--RESET LOGIC
	--clears the entire storage RAM
	process(ram_clk, reset_in)
	begin
	if (reset_in = '0') then
		--reset finished, get ready for next reset

		--reset the address buffers
		--reset_addr <= (others => '0');
		reset_addr <= "00000000";
	
		--take reset_out low
		reset_out <= '0';
	--increment the ram address
	elsif rising_edge(ram_clk) then
		--check if we have cleared all ram.
	 	if (reset_addr = addr_max) then
			reset_out <= '1';
		else
			--increment address by one on falling edge of ramclk
			reset_addr <= reset_addr + addr_incr;
		end if;
	end if;
	end process;
	




end Behavioral;
