----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    15:21:55 05/11/2013 
-- Design Name: 
-- Module Name:    display - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

use work.MEMORY.all;

entity dispcon_animations is
Port ( clk: in  STD_LOGIC;
		 animation: in unsigned (5 downto 0);
		 frame: in unsigned (9 downto 0); 
       srclk0,srclk1,srclk2: out  STD_LOGIC;
		 rclk0,rclk1,rclk2: out  STD_LOGIC;
		 clk_out0,clk_out1,clk_out2: out  STD_LOGIC;
		 ser_row0,ser_row1,ser_row2,ser_row3,ser_row4,ser_row5,ser_row6,ser_row7: out STD_LOGIC;
		 srclk_level,rclk_level,ser_level: out STD_LOGIC
		 );
end dispcon_animations;

architecture Behavioral of dispcon_animations is

signal ls_ser_level: unsigned (3 downto 0) := (others => '0');
signal hs_pwm: unsigned (8 downto 0) := (others => '0');
signal hs_ser: unsigned (4 downto 0) := (others => '0');

signal ls_counter0,ls_counter1: unsigned (8 downto 0) := (others => '0');
signal ls_clk_counter,hs_clk_counter: unsigned (25 downto 0) := (others => '0');
signal ls_clk,hs_clk: std_logic:='0';

signal ser_row0_anim, ser_row1_anim, ser_row2_anim, ser_row3_anim, ser_row4_anim, ser_row5_anim, ser_row6_anim, ser_row7_anim : unsigned (5 downto 0);

type type_ls_switching is array (0 to 15)
			of std_logic_vector (8 downto 0);
constant ls_switching : type_ls_switching :=(
"100000001",
"000000001",
"010000001",
"000000001",
"001000001",
"000000001",
"000100001",
"000000001",
"000010001",
"000000001",
"000001001",
"000000001",
"000000101",
"000000001",
"000000011",
"000000001"
);

begin

	--LOW SIDE

	process (clk)
	begin
		if (clk'event and clk='1') then
			ls_clk_counter <= ls_clk_counter + 1;
         if (ls_clk_counter =  93) then --93 234 421 609 1266 
				ls_clk <= NOT(ls_clk);
            ls_clk_counter <= (others => '0');
				
				if (ls_clk='1') then
					ls_ser_level <= ls_ser_level + 1;
					if ls_ser_level = 8 then
						ls_ser_level <= (others => '0');
						ls_counter0 <= ls_counter0 + 1;
						if ls_counter0 = 3 then
							ls_counter1 <= ls_counter1 + 1;
						end if;
						if ls_counter0 = 4 then
							ls_counter0 <= (others => '0');
							ls_counter1 <= ls_counter1 + 1;
							if ls_counter1 = 15 then
								ls_counter1 <= (others => '0');
							end if;
						end if;
					end if;
				end if;
			end if;
      end if;
	end process;
	
	srclk_level <= (ls_clk);
	rclk_level <= '1' when ls_ser_level=0 else '0';
	ser_level <= ls_switching(to_integer(ls_counter1))(to_integer(ls_ser_level));
	
	--HIGH SIDE

	process (clk,ls_counter0)
	begin
		if ls_counter0<1 then
			hs_clk <= '0';
			hs_clk_counter <= (others => '0');
			hs_pwm <= (others => '0');
			hs_ser <= (others => '0');
		elsif (clk'event and clk='1') then
			hs_clk_counter <= hs_clk_counter + 1;
         if (hs_clk_counter =  1) then --1 4 8 12 26
				hs_clk <= not(hs_clk);
            hs_clk_counter <= (others => '0');
					
				if (hs_clk='1') then
					hs_ser <= hs_ser + 1;
					if hs_ser = 25 then
						hs_ser <= (others => '0');
						hs_pwm <= hs_pwm + 1;
					end if;			
				end if;
				
         end if;
      end if;
	end process;

	srclk0 <= (hs_clk) when hs_ser<24 and hs_pwm<64 else '0';
	srclk1 <= (hs_clk) when hs_ser<24 and hs_pwm<64 else '0';
	srclk2 <= (hs_clk) when hs_ser<24 and hs_pwm<64 else '0';
	
	rclk0 <= '1' when hs_ser = 24 and hs_pwm<64 else '0';
	rclk1 <= '1' when hs_ser = 24 and hs_pwm<64 else '0';
	rclk2 <= '1' when hs_ser = 24 and hs_pwm<64 else '0';
	
	clk_out0 <= '1' when hs_ser > 24 and hs_pwm<64 else '0';
	clk_out1 <= '1' when hs_ser > 24 and hs_pwm<64 else '0';
	clk_out2 <= '1' when hs_ser > 24 and hs_pwm<64 else '0';
	
	with animation select
		ser_row0_anim <= --anim0(to_integer(ls_counter1/2)+8*to_integer(frame))(0)(to_integer(hs_ser)) when "000111",
							  anim1(to_integer(ls_counter1/2)+8*to_integer(frame))(0)(to_integer(hs_ser)) when "011011",
							  anim2(to_integer(ls_counter1/2)+8*to_integer(frame))(0)(to_integer(hs_ser)) when "001001",
							  anim3(to_integer(ls_counter1/2)+8*to_integer(frame))(0)(to_integer(hs_ser)) when "000011",
							  --anim4(to_integer(ls_counter1/2)+8*to_integer(frame))(0)(to_integer(hs_ser)) when "110001",
							  (others => '0') when others;
							  
	with animation select
		ser_row1_anim <= --anim0(to_integer(ls_counter1/2)+8*to_integer(frame))(1)(to_integer(hs_ser)) when "000111",
							  anim1(to_integer(ls_counter1/2)+8*to_integer(frame))(1)(to_integer(hs_ser)) when "011011",
							  anim2(to_integer(ls_counter1/2)+8*to_integer(frame))(1)(to_integer(hs_ser)) when "001001",
							  anim3(to_integer(ls_counter1/2)+8*to_integer(frame))(1)(to_integer(hs_ser)) when "000011",
							  --anim4(to_integer(ls_counter1/2)+8*to_integer(frame))(1)(to_integer(hs_ser)) when "110001",
							  (others => '0') when others;
							  
	with animation select
		ser_row2_anim <= --anim0(to_integer(ls_counter1/2)+8*to_integer(frame))(2)(to_integer(hs_ser)) when "000111",
							  anim1(to_integer(ls_counter1/2)+8*to_integer(frame))(2)(to_integer(hs_ser)) when "011011",
							  anim2(to_integer(ls_counter1/2)+8*to_integer(frame))(2)(to_integer(hs_ser)) when "001001",
							  anim3(to_integer(ls_counter1/2)+8*to_integer(frame))(2)(to_integer(hs_ser)) when "000011",
							  --anim4(to_integer(ls_counter1/2)+8*to_integer(frame))(2)(to_integer(hs_ser)) when "110001",
							  (others => '0') when others;
							  
	with animation select
		ser_row3_anim <= --anim0(to_integer(ls_counter1/2)+8*to_integer(frame))(3)(to_integer(hs_ser)) when "000111",
							  anim1(to_integer(ls_counter1/2)+8*to_integer(frame))(3)(to_integer(hs_ser)) when "011011",
							  anim2(to_integer(ls_counter1/2)+8*to_integer(frame))(3)(to_integer(hs_ser)) when "001001",
							  anim3(to_integer(ls_counter1/2)+8*to_integer(frame))(3)(to_integer(hs_ser)) when "000011",
							  --anim4(to_integer(ls_counter1/2)+8*to_integer(frame))(3)(to_integer(hs_ser)) when "110001",
							  (others => '0') when others;
							  
	with animation select
		ser_row4_anim <= --anim0(to_integer(ls_counter1/2)+8*to_integer(frame))(4)(to_integer(hs_ser)) when "000111",
							  anim1(to_integer(ls_counter1/2)+8*to_integer(frame))(4)(to_integer(hs_ser)) when "011011",
							  anim2(to_integer(ls_counter1/2)+8*to_integer(frame))(4)(to_integer(hs_ser)) when "001001",
							  anim3(to_integer(ls_counter1/2)+8*to_integer(frame))(4)(to_integer(hs_ser)) when "000011",
							  --anim4(to_integer(ls_counter1/2)+8*to_integer(frame))(4)(to_integer(hs_ser)) when "110001",
							  (others => '0') when others;
							  
	with animation select
		ser_row5_anim <= --anim0(to_integer(ls_counter1/2)+8*to_integer(frame))(5)(to_integer(hs_ser)) when "000111",
							  anim1(to_integer(ls_counter1/2)+8*to_integer(frame))(5)(to_integer(hs_ser)) when "011011",
							  anim2(to_integer(ls_counter1/2)+8*to_integer(frame))(5)(to_integer(hs_ser)) when "001001",
							  anim3(to_integer(ls_counter1/2)+8*to_integer(frame))(5)(to_integer(hs_ser)) when "000011",
							  --anim4(to_integer(ls_counter1/2)+8*to_integer(frame))(5)(to_integer(hs_ser)) when "110001",
							  (others => '0') when others;
							  
	with animation select
		ser_row6_anim <= --anim0(to_integer(ls_counter1/2)+8*to_integer(frame))(6)(to_integer(hs_ser)) when "000111",
							  anim1(to_integer(ls_counter1/2)+8*to_integer(frame))(6)(to_integer(hs_ser)) when "011011",
							  anim2(to_integer(ls_counter1/2)+8*to_integer(frame))(6)(to_integer(hs_ser)) when "001001",
							  anim3(to_integer(ls_counter1/2)+8*to_integer(frame))(6)(to_integer(hs_ser)) when "000011",
							  --anim4(to_integer(ls_counter1/2)+8*to_integer(frame))(6)(to_integer(hs_ser)) when "110001",
							  (others => '0') when others;
							  
	with animation select
		ser_row7_anim <= --anim0(to_integer(ls_counter1/2)+8*to_integer(frame))(7)(to_integer(hs_ser)) when "000111",
							  anim1(to_integer(ls_counter1/2)+8*to_integer(frame))(7)(to_integer(hs_ser)) when "011011",
							  anim2(to_integer(ls_counter1/2)+8*to_integer(frame))(7)(to_integer(hs_ser)) when "001001",
							  anim3(to_integer(ls_counter1/2)+8*to_integer(frame))(7)(to_integer(hs_ser)) when "000011",
							  --anim4(to_integer(ls_counter1/2)+8*to_integer(frame))(7)(to_integer(hs_ser)) when "110001",
							  (others => '0') when others;
	
	ser_row0 <= '1' when hs_ser<24 and hs_pwm < ser_row0_anim and (to_integer(ls_counter0)>0)  else '0';
	ser_row1 <= '1' when hs_ser<24 and hs_pwm < ser_row1_anim and (to_integer(ls_counter0)>0)  else '0';
	ser_row2 <= '1' when hs_ser<24 and hs_pwm < ser_row2_anim and (to_integer(ls_counter0)>0)  else '0';
	ser_row3 <= '1' when hs_ser<24 and hs_pwm < ser_row3_anim and (to_integer(ls_counter0)>0)  else '0';
	ser_row4 <= '1' when hs_ser<24 and hs_pwm < ser_row4_anim and (to_integer(ls_counter0)>0)  else '0';
	ser_row5 <= '1' when hs_ser<24 and hs_pwm < ser_row5_anim and (to_integer(ls_counter0)>0)  else '0';
	ser_row6 <= '1' when hs_ser<24 and hs_pwm < ser_row6_anim and (to_integer(ls_counter0)>0)  else '0';
	ser_row7 <= '1' when hs_ser<24 and hs_pwm < ser_row7_anim and (to_integer(ls_counter0)>0)  else '0';
	
end Behavioral;

