----------------------------------------------------------------------------------
-- Company: CIEMAT
-- Engineer: CRISTINA FERNÁNDEZ BEDOYA
-- 
-- Create Date:    12:44:45 04/19/2012 
-- Design Name: 
-- Module Name:    vme_patch - Behavioral 
-- Project Name:  VME_PATCH
-- Target Devices: Spartan 6 
-- Tool versions: 
-- Description: 
--
-- Revision: 
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_misc.all;
use work.pack.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;

entity vme_patch is
    Port ( 
     --GENERAL OPERATION LINES
           clk: in  STD_LOGIC;
			  LEDS: out  STD_LOGIC_VECTOR (1 downto 0);
			      --LED 0 pin 69 is D1 (SD OK)
				   --LED 1 pin 41 is D3 (DTACK)
			  TP: out  STD_LOGIC_VECTOR (1 downto 0);

     --I2C lines
           SDA : inout  STD_LOGIC;
           SCL : inout  STD_LOGIC;
           I2C_Add_p: out  STD_LOGIC_VECTOR (1 downto 0);
			  
	  --J2_OFCU output lines
--coger direct de VME	        ADD_J2 : out  STD_LOGIC_VECTOR (3 downto 0);
           DOUT_J2 : inout  STD_LOGIC_VECTOR (7 downto 0);
           Reset_J2 : out  STD_LOGIC;   --(reset_p)
           Write_J2 : inout  STD_LOGIC;   --(enw_x)
           Read_J2 : out  STD_LOGIC;   --(etr_x)
--           SP_indiv_J2 : in  STD_LOGIC_VECTOR (11 downto 0);
--           Spare_J2 : in  STD_LOGIC_VECTOR (4 downto 0);
           Spare_J2 : out STD_LOGIC;
           BRDSEL_J2 : out  STD_LOGIC_VECTOR (11 downto 0);
           DoutOE : out  STD_LOGIC;
           DoutDir : out  STD_LOGIC;
--poner Rs           SpindivOE : out  STD_LOGIC;
--poner Rs           SpindivDir : out  STD_LOGIC;
--poner Rs           spare234oe : out  STD_LOGIC;
--poner Rs           spare234dir : out  STD_LOGIC;
--poner a 0           OE_244 : out  STD_LOGIC;
 --poner a 0          OE_brdsel : out  STD_LOGIC;
     --OFCU
           SignalDetect_1: in std_logic_vector(2 downto 0);
           SignalDetect_2: in std_logic_vector(2 downto 0);
           SignalDetect_3: in std_logic_vector(2 downto 0);
           SignalDetect_4: in std_logic_vector(2 downto 0);
           SignalDetect_5: in std_logic_vector(2 downto 0);
           SignalDetect_6: in std_logic_vector(2 downto 0);
           SignalDetect_7: in std_logic_vector(2 downto 0);
           SignalDetect_8: in std_logic_vector(2 downto 0);
           SignalDetect_9: in std_logic_vector(2 downto 0);
           SignalDetect_10: in std_logic_vector(2 downto 0);
           SignalDetect_11: in std_logic_vector(2 downto 0);
           SignalDetect_12: in std_logic_vector(2 downto 0);
	
     --VME LINES
           --sysreset,  lo quito
			  brd_sel_16_p : in  STD_LOGIC;
      	  iack, iackin, ds0, ds1, as: in std_logic;
           Vwrite, lword: in std_logic;
 --quiero quitarlo          irq: out std_logic_vector(7 downto 1);
           irq_7: out std_logic;
           dtack_p, g245_p: out std_logic;
           iackout: out std_logic;
--           on_244, poner a 0
			  add_hold: out std_logic;
           add_p_1: in std_logic_vector(3 downto 0);
           add_p_2: in std_logic_vector(8 downto 5);
--           db: inout std_logic_vector(15 downto 0); no tengo pines, lo dejo en 8 bits
           db: inout std_logic_vector(7 downto 0);
-- comparador externo           add_mod: in std_logic_vector (5 downto 0)    
           add_mod_ok: in std_logic 
			  
			  );
end vme_patch;

architecture Behavioral of vme_patch is

component vmeifc port (
     clk: in std_logic;
     iack, ack_int, dtack_int, ds0, ds1: in std_logic;
     Vwrite, brd_sel, lword: in std_logic;
--     add_mod: in std_logic_vector (5 downto 0);
     add_mod_ok: in std_logic;
     DoutOE_p, OF_ENW, etr, enw, dtack, g245: out std_logic 
     );
end component;

component vmeint port (
     interrupt: in std_logic;  
     add, int_lev: in std_logic_vector(2 downto 0);
     iack, iackin, ds0, as, reset, clk: in std_logic;
     etr_ivec, int_rst, iackout: out std_logic;
     dtack_int, ack_int: out std_logic;
     irq: out std_logic_vector(7 downto 1)
	  ); 
end component;

component registros_vme port(
-- general
	clk, sysreset, etr, enw, cs: in std_logic;
	sda, scl: inout std_logic;
	I2C_Add_in: out  STD_LOGIC_VECTOR (1 downto 0);
	Reset_J2: out std_logic;
	rst_brdsel: out std_logic_vector(11 downto 0);
	local_reset_p: out std_logic;
	add: in std_logic_vector(3 downto 0);
	Spare_J2_int, Read_J2_int: out std_logic;  --25junio2013
	db_in: in std_logic_vector(7 downto 0);
	db_out: out std_logic_vector(7 downto 0);
	--ofcu
   SignalDetect_1: in std_logic_vector(2 downto 0);
   SignalDetect_2: in std_logic_vector(2 downto 0);
   SignalDetect_3: in std_logic_vector(2 downto 0);
   SignalDetect_4: in std_logic_vector(2 downto 0);
   SignalDetect_5: in std_logic_vector(2 downto 0);
   SignalDetect_6: in std_logic_vector(2 downto 0);
   SignalDetect_7: in std_logic_vector(2 downto 0);
   SignalDetect_8: in std_logic_vector(2 downto 0);
   SignalDetect_9: in std_logic_vector(2 downto 0);
   SignalDetect_10: in std_logic_vector(2 downto 0);
   SignalDetect_11: in std_logic_vector(2 downto 0);
   SignalDetect_12: in std_logic_vector(2 downto 0);
	force_led: out std_logic;--4july2013
-- interrupciones
	int_rst, etr_ivec: in std_logic;
	interrupt: out std_logic;  
	int_lev_p: out std_logic_vector(2 downto 0)
	);
end component;

component leds_clock port(
-- general
	clk, local_reset: in std_logic;
	OUTclk_slow: out std_logic
 	);
end component;


component stretch port (
	clk_1, clk_2, din, reset: in std_logic;
	dout: out std_logic
	);		
end component;


signal db_in, db_out: std_logic_vector (7 downto 0);
signal local_reset, g245: std_logic;
signal add_in: std_logic_vector (8 downto 0);

-- interrupciones
signal interrupt, ack_int, dtack_int: std_logic;
signal etr_ivec, int_rst: std_logic;
signal int_lev: std_logic_vector(2 downto 0);

signal cs, etr, enw, dtack: std_logic;

signal add_ofcu_brdsel: std_logic_vector(3 downto 0);

signal OF_ENW,OF_ENR,J2_BRDSEL: std_logic;
signal aux, of_enr1, of_enr2: std_logic;
signal irq: std_logic_vector(7 downto 1);
signal sysreset: std_logic;

signal rst_brdsel: std_logic_vector(11 downto 0);
signal OUTclk_slow: std_logic;

signal leddtack,ledsignalchk,signalcheck: std_logic;

signal Reset_J2_i: std_logic;

signal BRDSEL_J2_i: std_logic_vector(11 downto 0);
signal DoutOE_p: std_logic;

signal as_v1, as_v2,myas,brd_sel_16, asdel: std_logic;
signal dsdly, dsdly1, dsvalid: std_logic;

signal I2C_Add_in: std_logic_vector(1 downto 0);

signal Spare_J2_int, Read_J2_int: std_logic; --25june2013

signal force_led: std_logic; --4july2013
signal brd_sel_16_ifc: std_logic; --1 agust 2013

signal selbrd: std_logic_vector (11 downto 0); --28oct2013

begin

U1: vmeifc port map(
     clk=>clk, 
     iack=>iack, ack_int=>ack_int, dtack_int=>dtack_int, ds0=>ds0, ds1=>ds1, 
     Vwrite=>Vwrite, brd_sel=>brd_sel_16_ifc, lword=>lword, 
     add_mod_ok=>add_mod_ok, 
     DoutOE_p=> DoutOE_p, OF_ENW =>OF_ENW,
	  etr=>etr, enw=>enw, dtack=>dtack, g245=>g245  
     );

U2: vmeint port map (
     interrupt=>interrupt, --: in std_logic;  
     add=>add_in(2 downto 0), int_lev=>int_lev, --: in std_logic_vector(2 downto 0);
     iack=>iack, iackin=>iackin, ds0=>ds0, as=>as, reset=>sysreset, clk=>clk, 
     etr_ivec=>etr_ivec, int_rst=>int_rst, iackout=>iackout, --: out std_logic;
     dtack_int=>dtack_int, ack_int=>ack_int, --: out std_logic;
     irq=>irq --: out std_logic_vector(7 downto 1)); 
     );

U3: registros_vme port map(
-- general
	clk=>clk, sysreset=>sysreset, 
	etr=>etr, enw=>enw, cs=>cs,
	sda=>SDA, scl=>SCL,
	I2C_Add_in => I2C_Add_in,
	Reset_J2 => Reset_J2_i,
	rst_brdsel=>rst_brdsel,
	local_reset_p=>local_reset,
	add=>add_in (3 downto 0),
	Spare_J2_int=> Spare_J2_int, Read_J2_int=>Read_J2_int, --25junio2013
	db_in=>db_in,
	db_out=>db_out,
	--ofcu
   SignalDetect_1=> SignalDetect_1,
   SignalDetect_2=> SignalDetect_2,
   SignalDetect_3=> SignalDetect_3,
   SignalDetect_4=> SignalDetect_4,
   SignalDetect_5=> SignalDetect_5,
   SignalDetect_6=> SignalDetect_6,
   SignalDetect_7=> SignalDetect_7,
   SignalDetect_8=> SignalDetect_8,
   SignalDetect_9=> SignalDetect_9,
   SignalDetect_10=> SignalDetect_10,
   SignalDetect_11=> SignalDetect_11,
   SignalDetect_12=> SignalDetect_12,
	force_led => force_led, --4july2013
-- interrupciones
	int_rst=>int_rst, etr_ivec=>etr_ivec,
	interrupt=>interrupt,  
	int_lev_p=>int_lev
	);

U4: leds_clock  port map(
	clk=> clk, local_reset=> local_reset,
	OUTclk_slow=>OUTclk_slow
 	);

--leds a 0 se encienden, a 1 se apagan
LEDS(0) <= ledsignalchk and not(force_led);

I2C_Add_p <= I2C_Add_in;

signalcheck <= '1' when 
					SignalDetect_1="111" and 
					SignalDetect_2="111" and 
					SignalDetect_3="111" and 
					SignalDetect_4="111" and 
					SignalDetect_5="111" and 
					SignalDetect_6="111" and 
					SignalDetect_7="111" and 
					SignalDetect_8="111" and 
					SignalDetect_9="111" and 
					SignalDetect_10="111" and 
					SignalDetect_11="111" and 
					SignalDetect_12="111" else '0';
	
U5: stretch port map(clk, OUTclk_slow, signalcheck, local_reset, ledsignalchk);


LEDS(1) <= leddtack; 
U6: stretch port map(clk, OUTclk_slow, dtack, local_reset, leddtack);


TP(0) <= OF_ENW; --'1' when (SP_indiv_J2="000000000000") else '0';--: in  STD_LOGIC_VECTOR (11 downto 0);
--TP(1) <= '1' when (Spare_J2="00000") else '0';--: in  STD_LOGIC_VECTOR (4 downto 0); 
TP(1) <= '1' when (Spare_J2_int='0' and Read_J2_int='0') else '0';--: in  STD_LOGIC_VECTOR (4 downto 0); 

Spare_J2 <= Spare_J2_int;
Read_J2 <= Read_J2_int;
 

sysreset <= '0';--No lo uso

irq_7 <= irq(7);
 
--ADDRESS
--add_p_1: in std_logic_vector(3 downto 0);
--add_p_2: in std_logic_vector(8 downto 5);
add_in <= add_p_2 & '0' & add_p_1;
--coger directamente de VME       ADD_J2 <=  add_in(3 downto 0);

process(clk)
begin
  if clk'event and clk='1' then
	    as_v1 <= as;
	    as_v2 <= as_v1;
  end if;
end process;

--myas<= (as_v1 xor as_v2) and as_v2;
myas<= (as_v1 xor as_v2) and not(as);
asdel <= (as_v1 xor as_v2) and as;

process(clk,myas, asdel)
begin
	if clk'event and clk='1' then
		if myas='1' then
			add_ofcu_brdsel <= add_in (8 downto 5);
			brd_sel_16_ifc <= brd_sel_16_p;
		elsif asdel='1' then
			add_ofcu_brdsel <= "0000";
			brd_sel_16_ifc <= '1';
		end if;
	end if;
end process;

brd_sel_16 <= brd_sel_16_p;

cs <= '1' when (brd_sel_16='0' and add_ofcu_brdsel="0000") else '0';


process(clk,myas, asdel)
begin
	if clk'event and clk='1' then
		if (myas='1' and brd_sel_16='0' and as='0') then
			if (add_in(8 downto 5)="0001") then
			   selbrd(0) <= '1';
			else
				selbrd(0) <= '0';
			end if;
			if (add_in(8 downto 5)="0010") then
			   selbrd(1) <= '1';
			else
				selbrd(1) <= '0';
			end if;
			if (add_in(8 downto 5)="0011") then
			   selbrd(2) <= '1';
			else
				selbrd(2) <= '0';
			end if;
			if (add_in(8 downto 5)="0100") then
			   selbrd(3) <= '1';
			else
				selbrd(3) <= '0';
			end if;
			if (add_in(8 downto 5)="0101") then
			   selbrd(4) <= '1';
			else
				selbrd(4) <= '0';
			end if;
			if (add_in(8 downto 5)="0110") then
			   selbrd(5) <= '1';
			else
				selbrd(5) <= '0';
			end if;
			if (add_in(8 downto 5)="0111") then
			   selbrd(6) <= '1';
			else
				selbrd(6) <= '0';
			end if;
			if (add_in(8 downto 5)="1000") then
			   selbrd(7) <= '1';
			else
				selbrd(7) <= '0';
			end if;
			if (add_in(8 downto 5)="1001") then
			   selbrd(8) <= '1';
			else
				selbrd(8) <= '0';
			end if;
			if (add_in(8 downto 5)="1010") then
			   selbrd(9) <= '1';
			else
				selbrd(9) <= '0';
			end if;
			if (add_in(8 downto 5)="1011") then
			   selbrd(10) <= '1';
			else
				selbrd(10) <= '0';
			end if;
			if (add_in(8 downto 5)="1100") then
			   selbrd(11) <= '1';
			else
				selbrd(11) <= '0';
			end if;
		elsif asdel='1' then
			selbrd(11 downto 0) <= (others =>'0');
		end if;
	end if;
end process;

BRDSEL_J2_i(0) <= J2_BRDSEL when (selbrd(0)='1') else rst_brdsel(0); --0x40
BRDSEL_J2_i(1) <= J2_BRDSEL when (selbrd(1)='1') else rst_brdsel(1); --0x80
BRDSEL_J2_i(2) <= J2_BRDSEL when (selbrd(2)='1') else rst_brdsel(2); --0xC0
BRDSEL_J2_i(3) <= J2_BRDSEL when (selbrd(3)='1') else rst_brdsel(3); --0X100
BRDSEL_J2_i(4) <= J2_BRDSEL when (selbrd(4)='1') else rst_brdsel(4); --0X140
BRDSEL_J2_i(5) <= J2_BRDSEL when (selbrd(5)='1') else rst_brdsel(5); --0X180
BRDSEL_J2_i(6) <= J2_BRDSEL when (selbrd(6)='1') else rst_brdsel(6); --0X1C0
BRDSEL_J2_i(7) <= J2_BRDSEL when (selbrd(7)='1') else rst_brdsel(7); --0X200
BRDSEL_J2_i(8) <= J2_BRDSEL when (selbrd(8)='1') else rst_brdsel(8); --0X240
BRDSEL_J2_i(9) <= J2_BRDSEL when (selbrd(9)='1') else rst_brdsel(9); --0X280
BRDSEL_J2_i(10) <= J2_BRDSEL when (selbrd(10)='1') else rst_brdsel(10); --0X2C0
BRDSEL_J2_i(11) <= J2_BRDSEL when (selbrd(11)='1') else rst_brdsel(11); --0X300

--BRDSEL_J2_i(0) <= J2_BRDSEL when (brd_sel_16='0' and add_ofcu_brdsel="0001" and as='0') else rst_brdsel(0); --0x40
--BRDSEL_J2_i(1) <= J2_BRDSEL when (brd_sel_16='0' and add_ofcu_brdsel="0010" and as='0') else rst_brdsel(1); --0x80
--BRDSEL_J2_i(2) <= J2_BRDSEL when (brd_sel_16='0' and add_ofcu_brdsel="0011" and as='0') else rst_brdsel(2); --0xC0
--BRDSEL_J2_i(3) <= J2_BRDSEL when (brd_sel_16='0' and add_ofcu_brdsel="0100" and as='0') else rst_brdsel(3); --0X100
--BRDSEL_J2_i(4) <= J2_BRDSEL when (brd_sel_16='0' and add_ofcu_brdsel="0101" and as='0') else rst_brdsel(4); --0X140
--BRDSEL_J2_i(5) <= J2_BRDSEL when (brd_sel_16='0' and add_ofcu_brdsel="0110" and as='0') else rst_brdsel(5); --0X180
--BRDSEL_J2_i(6) <= J2_BRDSEL when (brd_sel_16='0' and add_ofcu_brdsel="0111" and as='0') else rst_brdsel(6); --0X1C0
--BRDSEL_J2_i(7) <= J2_BRDSEL when (brd_sel_16='0' and add_ofcu_brdsel="1000" and as='0') else rst_brdsel(7); --0X200
----BRDSEL_J2_i(8) <= J2_BRDSEL when (brd_sel_16='0' and add_ofcu_brdsel="1001" and as='0') else rst_brdsel(8); --0X240
--BRDSEL_J2_i(9) <= J2_BRDSEL when (brd_sel_16='0' and add_ofcu_brdsel="1010" and as='0') else rst_brdsel(9); --0X280
--BRDSEL_J2_i(10) <= J2_BRDSEL when (brd_sel_16='0' and add_ofcu_brdsel="1011" and as='0') else rst_brdsel(10); --0X2C0
--BRDSEL_J2_i(11) <= J2_BRDSEL when (brd_sel_16='0' and add_ofcu_brdsel="1100" and as='0') else rst_brdsel(11); --0X300

BRDSEL_J2 <= BRDSEL_J2_i;

Reset_J2 <= Reset_J2_i;

J2_BRDSEL <= '1' when (OF_ENR='1' and dsvalid='0') --READ cycle  alargar esto con un registro unos ciclos
              else '1' when ((OF_ENW='1') and dsvalid='0')--WRITE cycle 
				  else '0';

OF_ENR <= '1' when (brd_sel_16='0' and cs='0' and Vwrite='1') else '0';

process(clk)
begin
 if clk'event and clk='1' then
   dsdly <= ds0;
	dsdly1 <= dsdly;
	dsvalid <= ds0 and dsdly;
 end if;
 end process;


--VME signals	
dtack_p <= dtack;
g245_p <= g245;
--no tengo pines on_244 <= '0';     

add_hold <= not (ds0 and ds1);
   
--VME data bus
db <= db_out when ((etr='0' and cs='1') or etr_ivec='0')  --READ cycle 
      else DOUT_J2 when OF_ENR='1'  --READ cycle OFCU
      else (others => 'Z'); 
db_in <= db; --WRITE CYCLE

Write_J2 <=(Vwrite) when Reset_J2_i='0' else '0'; --(enw) 1 means writing in OFCU, 0 reading from OFCU, otherway around for VME

DOUT_J2 <= db_in(7 downto 0) when (brd_sel_16='0' and cs='0' and Vwrite='0') 
            else (others => 'Z'); --READ cycle  
				
DoutDir <= '1' when Vwrite='0'   --WRITE cycle
            else '0'; --READ cycle
				--should be 1 for writing to OFCU and 0 for reading from OFCU

DoutOE <= DoutOE_p;			


--Read_J2 <='Z'; --(etr) For the moment, it is a spare, we use a pulse in BRDSEL_J2

end Behavioral;

