----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    12:04:55 07/09/2012 
-- Design Name: 
-- Module Name:    registers - 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 itantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

library WORK;
use WORK.common.ALL;

entity registers is
    Port (
		i 		: in t_registers_i;
		o 		: out t_registers_o;
		sc_data	: inout std_logic_vector(7 downto 0);
		clk40 : in std_logic
	 );
end registers;

architecture Behavioral of registers is


	


	
	
	
--	type reg_t is array(natural range <>) of std_logic_vector(7 downto 0);
	
	signal reg : reg_t(num_of_regs-1 downto 0) 		:= reg_init;
	signal reg_int : reg_t(num_of_regs-1 downto 0)	:= (others => (others =>'0'));
	signal reg_ext : reg_t(num_of_regs-1 downto 0)	:= (others => (others =>'0'));
	
	signal reg_ch_ext : std_logic_vector(num_of_regs-1 downto 0)	:= (others => '0');
	signal reg_ch_ext2 : std_logic_vector(num_of_regs-1 downto 0)	:= (others => '0');
	signal reg_ch_int : std_logic_vector(num_of_regs-1 downto 0)	:= (others => '0');
	signal reg_ch_int2 : std_logic_vector(num_of_regs-1 downto 0) 	:= (others => '0');
--	signal reg_ch_int3 : std_logic_vector(num_of_regs-1 downto 0)	:= (others => '0');
--	signal reg_ch_int4 : std_logic_vector(num_of_regs-1 downto 0)	:= (others => '0');
	
	signal reg_ed_ext : std_logic_vector(num_of_regs-1 downto 0)	:= (others => '0');
	signal reg_ed_int : std_logic_vector(num_of_regs-1 downto 0)	:= (others => '0');

	type t_ctrlstate is (idle, waiting);
	signal ctrlstate : t_ctrlstate := idle;


begin


o.reg <= reg;
o.reg_ch_int <= i.reg_ch_int;

o.leds(2 downto 2) <= reg(test_reg)(0 downto 0);
o.leds(3) <= reg_ed_ext(test_reg);
o.leds(4) <= i.sc_wr;
o.leds(5) <= i.sc_bsel;

process (clk40)
	variable reg_id 	: integer range num_of_regs-1 downto 0 	:= 0;
	constant sc_bsel_dly : integer := 1;
	variable sc_bsel_d : std_logic_vector(sc_bsel_dly-1 downto 0) := (others => '0');
	variable reg_id_redone : std_logic_vector(3 downto 0);
	variable dindon : std_logic;
begin 
	if rising_edge(clk40) then
		reg_id := to_integer(unsigned(i.sc_add(3 downto 0)));
		case ctrlstate is
			when idle =>
				o.leds(1) <= '0';
				dindon := not dindon;
--				o.leds(5 downto 2) <= (others => dindon);
				if sc_bsel_d(0) = '1' and i.sc_wr = '1' then
					reg_ch_ext(reg_id) <= not reg_ch_ext(reg_id);
					reg_ext(reg_id) <= sc_data;
					ctrlstate <= waiting;
				elsif sc_bsel_d(0) = '1' and i.sc_wr = '0' then
					sc_data <= reg(reg_id);
--					o.leds(5 downto 2) <= reg(reg_id)(3 downto 0);
					ctrlstate <= waiting;
				end if;
			when others =>
				o.leds(1) <= '1';
				if sc_bsel_d(0) = '0' then
					sc_data <= (others => 'Z');
					
					ctrlstate <= idle;
				end if;
		end case;
		
--		o.leds(2) <= sc_bsel_d(0);
--		o.leds(3) <= i.sc_wr;
		reg_id_redone := std_logic_vector(to_unsigned(reg_id,4));
--		o.leds(5 downto 2) <= reg_id_redone(3 downto 0);
		
		
		if sc_bsel_dly > 1 then sc_bsel_d(sc_bsel_dly - 2 downto 0) :=sc_bsel_d(sc_bsel_dly - 1 downto 1);
		end if;
		sc_bsel_d(sc_bsel_dly - 1) := i.sc_bsel;
		
		reg_ch_ext2 <= reg_ch_ext;
		reg_ed_ext <= reg_ch_ext2 xor reg_ch_ext;
		o.ext_wr <= reg_ed_ext;
		
		reg_ch_int2 <= i.reg_ch_int;
		reg_ed_int <= reg_ch_int2 xor i.reg_ch_int;
		
		for r in num_of_regs-1 downto 0 loop
			if reg_mode(r) = '1' and reg_ed_ext(r)='1' then reg(r)<=reg_ext(r);
			elsif reg_ed_int(r) = '1' then 
				reg(r) <= i.reg_int(r);
			end if;
		end loop;
		
		
	end if;
end process;






end Behavioral;

