library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_misc.all;
use work.pack.all;

entity rosvme is port(
-- VME general
     clk, sysreset, brd_sel_16, brd_sel_24: in std_logic;  -- sysreset activo alto
	  iack, iackin, ds0, ds1, as: in std_logic;
     write, lword: in std_logic;
     add_mod: in std_logic_vector (5 downto 0);
     dtack_p, g245_p, iackout: out std_logic;
     add_p: in std_logic_vector(8 downto 0);
     add_f_p: out std_logic_vector(15 downto 9); --No las uso, era para la FLASH
     db: inout std_logic_vector(15 downto 0);
     irq: out std_logic_vector(7 downto 1);
     on_244, add_hold: out std_logic;
     etr_vf, enw_vf: out std_logic;
-- ROS general
     clk_slow: in std_logic;
     sel_tim_p: in std_logic;
	  etr_x, enw_x, prs, mrs, reset_p: out std_logic;
     cscr_p: out std_logic_vector (6 downto 0);
     --dec10 spaf, sff: in std_logic_vector (4 downto 0);
	  spaf, sff: in std_logic_vector (3 downto 0);
	  hardresetin: in std_logic; --dec10 de rosctrl por el pin de sff4
	  softrst_rsctrl_p: out std_logic; --dec10 a rosctrl, softrst directo (ademas del de rosmem), era spaf4
	  softreset_p: out std_logic; --dec10 era el pin de vspare0, no va directa a rosctrl
	  ldpreg: out std_logic;	-- faltaba esta linea, uso TP1 que es pin 64
--SPARES
		mspare_3,mspare_2,mspare_1,mspare_0: in std_logic; --dec10 era out
		cspare_8,cspare_9: in std_logic; --dec10 era out
		--dec10 vspare_1,vspare_0: out std_logic;
		vspare_1: in std_logic; --dec10 era out
-- ROS control
     ros_waiting: in std_logic;
-- ROSMEM control
     mem_done, g245_mem, dtack_mem: in std_logic;
-- TIM
     evcnt_res: in std_logic;
     sel_tim_clk: out std_logic_vector (1 downto 0);
-- FPGA
     fpga_done: in std_logic_vector (4 downto 0);
     cclk, fpga_init: out std_logic_vector(4 downto 0);
	  prgm_fpga_p: out std_logic_vector(4 downto 0);
 --FLASH FPGA    
     flash_tdo_p: in std_logic_vector (5 downto 0);     -- 5  es RosMEM
     flash_tck_p: out std_logic_vector (5 downto 0);    -- 5  es RosMEM
     fl_switch: in std_logic_vector (2 downto 0);
     flash_tdi_p, flash_tms_p: out std_logic;
     fl_tck, fl_tms, fl_tdi: in std_logic;
     fl_tdo: out std_logic;                                
-- GOL Y QPLL
     gol_ready: in std_logic;	                    
     qpll_error, qpll_locked: in std_logic;
     gol_off, gol_reset, qpll_reset: out std_logic;
-- LEDs
     intrpt_led, dtack_led, spare_led: out std_logic;
-- I2C bus (para GOL y 1-wire)
     i2c_reset, i2c_ce_p, i2c_rd, i2c_wr: out std_logic; -- dejamos i2c_intrpt
     i2c_ce_gol, i2c_ce_1wire: out std_logic;
	  i2c_int_p: in std_logic; --NO la uso, falta un pull-up
--TEST POINTS
	    tp2: out std_logic; 
	    tp3: out std_logic; 
	    tp4: out std_logic
     );
end rosvme ;

architecture arch of rosvme is

component vmeifc port (
     clk: in std_logic;
     iack, ack_int, dtack_int, ds0, ds1: in std_logic;
     write, brd_sel, lword: in std_logic;
     add_mod: in std_logic_vector (5 downto 0);
     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, discon_vme: in std_logic;
     iack, iackin, ds0, as, reset, clk: in std_logic;
     etr_ivec, int_rst, iackout: out std_logic;
     dtack_int, ack_int: out std_logic;
 --    aux_int: out std_logic;
     irq: out std_logic_vector(7 downto 1)); 
end component;


component rv_registros port(
-- general
     clk, sysreset, etr, enw, cs: in std_logic;
	  sda, scl: out std_logic; --abril12  CUOF
	  soft_reset: out std_logic;
	  sel_tim: in std_logic;
     add: in std_logic_vector(5 downto 0);
     db_in: in std_logic_vector(15 downto 0);
     db_out: out std_logic_vector(15 downto 0);
-- ROS general
     prs, mrs, reset: out std_logic;
 	  ldpreg: out std_logic;
--dec10     spaf, sff, fpga_done: in std_logic_vector (4 downto 0);
     fpga_done: in std_logic_vector (4 downto 0); --dec10
 	  hardresetin: in std_logic; --dec10 de rosctrl por el pin de sff4
     spaf, sff: in std_logic_vector (3 downto 0); --dec10
-- ROS control
     ros_waiting: in std_logic;
-- ROSMEM control
     mem_done: in std_logic;
-- TIM
     evcnt_res: in std_logic;
     sel_tim_clk_p: out std_logic_vector (1 downto 0);
-- FPGA y flash XC18V01
     cclk, fpga_init_p: out std_logic_vector(4 downto 0);
	  prgm_fpga_p: out std_logic_vector(4 downto 0);
     flash_tck_p: out std_logic_vector (5 downto 0);
     flash_tdo: in std_logic_vector (5 downto 0);
     flash_tdi_p, flash_tms_p, ena_evres_prgm_p: out std_logic;
	  fl_vme_p: out std_logic_vector(2 downto 0);
	  flash_ena_5_rosmem: out std_logic;
-- GOL Y QPLL
     gol_ready: in std_logic;	
     qpll_error, qpll_locked: in std_logic;
     gol_off_p: out std_logic;
-- I2C bus (para GOL y 1-wire)
     i2c_ce, i2c_rd, i2c_wr: out std_logic; -- i2c_intrpt
     i2c_ce_gol_p, i2c_ce_1wire_p: out std_logic;
-- 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 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 (15 downto 0);
signal reset, g245: std_logic;
signal add_in: std_logic_vector (8 downto 0);
signal prgm_fpga: std_logic_vector (4 downto 0);
signal ena_evres_prgm: std_logic;

------------

-- 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, i2c_ce: std_logic;
signal disp_led, led_pulse: std_logic_vector(2 downto 0);
signal cscr: std_logic_vector (7 downto 0);

-- jtag-vme mux
signal flash_tdo, flash_tck: std_logic_vector (5 downto 0);
signal flash_tdi, flash_tms: std_logic;
signal fl_tdo_aux,fl_tdo_r, fl_tms_r, fl_tdi_r, fl_tck_r: std_logic;
signal fl_vme: std_logic_vector(2 downto 0);
signal fl_sel:std_logic_vector(2 downto 0);

signal sel_tim:std_logic;
signal soft_reset, qpll_reset_vme:std_logic;
signal flash_ena_5_rosmem: std_logic;

signal gol_reset_vme:std_logic;

--dic10 creo un reset i2c vme
signal i2c_reset_vme:std_logic;

signal sda, scl: std_logic; --abril12  CUOF

begin
----------------------TEST POINTS----------------
tp2<= etr or brd_sel_24;	 --TP2	pin 103		  --abril12  CUOF
tp3 <=reset or i2c_int_p;	 --TP3	pin 155	  --abril12  CUOF
tp4 <= clk; --TP4	 pin 160
-----SPARES
--etr_vf <= brd_sel_24;  --abril12  CUOF
--enw_vf <= i2c_int_p;	   --abril12  CUOF
etr_vf <= sda;  --abril12  CUOF
enw_vf <= scl;	   --abril12  CUOF

--dec10 mspare_3 <= 'Z';
--dec10 mspare_2 <= 'Z';
--dec10 mspare_1 <= 'Z';
--dec10 mspare_0 <='Z';
--dec10 vspare_1 <='Z';
--dec10 cspare_9 <='Z';
--dec10 cspare_8 <='Z';

add_f_p <= (others=>'Z');
----------------------------------------------------------------------------------
-- puertos
reset_p <= reset; --hard reset
--dec10 vspare_0 <=soft_reset; --soft reset
softreset_p <= soft_reset; --dec10 cambio nombre
softrst_rsctrl_p <= soft_reset; --dec10 la que va directa a rosctrl

--gol_reset <= not (reset); --gol TIENE el reset activo baja  
gol_reset_vme <=  not(db_in(11)) when  add_in(5 downto 0)="001001" and cs='1' and enw='1' else '1'; --gol TIENE el reset activo baja  
gol_reset <= gol_reset_vme and not(reset); 

qpll_reset_vme <= not(db_in(8)) when  add_in(5 downto 0)="001001" and cs='1' and enw='1' else '1';	 --qpll tiene el reset activo baja
qpll_reset <= qpll_reset_vme and not(reset);

--dic10 creo un reset i2c vme
i2c_reset_vme <= not(db_in(12)) when  add_in(5 downto 0)="001001" and cs='1' and enw='1' else '1';	 --I2C tiene el reset activo baja
i2c_reset <= i2c_reset_vme and not (reset);  -- pca9564 tiene el reset activo baja

i2c_ce_p <= i2c_ce;
cscr_p <= cscr (6 downto 0);
sel_tim <= sel_tim_p;

-- LEDS
     --output
intrpt_led <= led_pulse(0);
dtack_led <= led_pulse(1);
spare_led <= not led_pulse (2);
     --input
disp_led(0) <= int_rst;
disp_led(1) <= (dtack or dtack_int or ((not flash_ena_5_rosmem) and dtack_mem));
disp_led(2) <= enw;
     
ULED1: stretch port map(clk, clk_slow, disp_led(0), reset, led_pulse(0));
ULED2: stretch port map(clk, clk_slow, disp_led(1), reset, led_pulse(1));
ULED3: stretch port map(clk, clk_slow, disp_led(2), reset, led_pulse(2));

--------------
U1: vmeifc port map(
     clk=>clk, --: in std_logic;
     iack=>iack, ack_int=>ack_int, dtack_int=>dtack_int, ds0=>ds0, ds1=>ds1, --: in std_logic;
     write=>write, brd_sel=>brd_sel_16, lword=>lword, --: in std_logic;
     add_mod=>add_mod, --: in std_logic;
     etr=>etr, enw=>enw, dtack=>dtack, g245=>g245 --: out std_logic 
     );


U3: 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)); 
     );

U5: rv_registros port map(
-- general
     clk=>clk, sysreset=>sysreset, etr=>etr, enw=>enw, cs=>cs, --: in std_logic;
	   sda=> sda, scl=> scl, --abril12  CUOF
		soft_reset=>soft_reset,
 	  sel_tim=> sel_tim,
     add=>add_in (5 downto 0), --: in std_logic_vector(5 downto 0);
     db_in=> db_in, --: in std_logic_vector(15 downto 0);
     db_out=>db_out, --: out std_logic_vector(15 downto 0);
-- ROS general
     prs=>prs, mrs=>mrs, reset=>reset, --: out std_logic;
 	  ldpreg => ldpreg,
--dec10     spaf=>spaf, sff=>sff, fpga_done=>fpga_done, --: in std_logic_vector (4 downto 0);
	  fpga_done=>fpga_done, --: in std_logic_vector (4 downto 0);
	  hardresetin=>hardresetin, --dec10
     spaf=>spaf, sff=>sff, 
-- ROS control
     ros_waiting=>ros_waiting, --: in std_logic;
-- ROSMEM control
     mem_done=>mem_done, --: in std_logic;
-- TIM
     evcnt_res=>evcnt_res, --: in std_logic;
     sel_tim_clk_p=>sel_tim_clk, --: out std_logic_vector (1 downto 0);
-- FPGA y flash XC18V01
     cclk=>cclk, fpga_init_p=>fpga_init, flash_tck_p=>flash_tck, prgm_fpga_p=>prgm_fpga, --: out std_logic_vector(4 downto 0);
     flash_tdo=>flash_tdo, --: in std_logic_vector (4 downto 0);
     flash_tdi_p=>flash_tdi, flash_tms_p=>flash_tms, ena_evres_prgm_p=>ena_evres_prgm, --: out std_logic;
	  fl_vme_p =>fl_vme,
	  flash_ena_5_rosmem=>flash_ena_5_rosmem,
-- GOL Y QPLL
     gol_ready=>gol_ready, --: in std_logic;	
     qpll_error=>qpll_error, qpll_locked=>qpll_locked, --: in std_logic;
     gol_off_p=>gol_off, --: out std_logic;
-- I2C bus (para GOL y 1-wire)
     i2c_ce=>i2c_ce, i2c_rd=>i2c_rd, i2c_wr=>i2c_wr, --: out std_logic; -- i2c_intrpt
     i2c_ce_gol_p=>i2c_ce_gol, i2c_ce_1wire_p=>i2c_ce_1wire, --: out std_logic;
-- interrupciones
     int_rst=>int_rst, etr_ivec=>etr_ivec, --: in std_logic;
     interrupt=>interrupt, --: out std_logic;  
     int_lev_p=>int_lev --: out std_logic_vector(2 downto 0))
     );


------------------ACCESO VME------------------------------------
--CHIP SELECT FOR VME
gencs: for igen in cscr'range generate
   cscr(igen) <= '1' when (brd_sel_16='0' and add_in(add_in'high downto add_in'high-2)=igen) else '0';
end generate;

cs <= cscr(cscr'high); -- chip select local

--ADD9-ADD7	CSCR
-- 0           CEROS 0
-- 1           CEROS 1
-- 2           CEROS 2
-- 3           CEROS 3
-- 4           CEROS 4 (canal 24 en RosCTRL)
-- 5           RosCTRL
-- 6           RosMEM
-- 7           RosVME (local)
----------------------------------------------------

etr_x <= etr;
enw_x <= enw;
	
dtack_p <= (dtack or ((not flash_ena_5_rosmem) and dtack_mem));

--add_hold <= not (ds0 and ds1 and as); LINCO ago07
add_hold <= not (ds0 and ds1);-- and as);


g245_p <= (g245 and ((not flash_ena_5_rosmem) and g245_mem));
on_244 <= '0';                                          -- activo bajo, inhabilitado cuando VME FLASH -> FPGA

-- data bus; desactivar cuando se selecciona PCA9564
db <= db_out when ((etr='0' and cs='1' and i2c_ce='1') or etr_ivec='0')  else (others => 'Z');  -- i2c_ce del PCA9564 es activo bajo
db_in <= db;

add_in <= add_p;


------------------------------CARGA DE LAS FLASH-------------------
--SWITCH BCD
--0 ceros(0)
--1 ceros(1)
--2 ceros(2)
--3 ceros(3)
--4 rosctrl
--5 rosmem
--6 Desde el VME
--7 seleccionas lo que cargas desde el VME registro $0A

--seņales que van al conector J1: fl_tdo, fl_tdi, fl_tms, fl_tck
--seņales que vienen de un registro VME: flash_tdo, flash_tdi, flash_tms, flash_tck
--seņales que salen de los pines de ROSVME y van a las distintas flash: flash_tdo_p, flash_tms_p, flash_tdi_p, flash_tck_p
--fl_sel <= fl_aux when fl_switch="111" else fl_switch;
fl_sel <= fl_switch when fl_vme="111" else fl_vme;  --lo pongo para que mande el VME

flash_tdi_p <= flash_tdi when fl_sel="110" else fl_tdi_r;
flash_tms_p <= flash_tms when fl_sel="110" else fl_tms_r;

--TDO
tdogen: for itdo in flash_tdo'range generate
flash_tdo(itdo) <= flash_tdo_p(itdo) when fl_sel="110" else '0';
end generate;

fl_tdo_aux <= flash_tdo_p(0) when fl_sel="000" else
		flash_tdo_p(1) when fl_sel="001" else
		flash_tdo_p(2) when fl_sel="010" else
		flash_tdo_p(3) when fl_sel="011" else
		flash_tdo_p(4) when fl_sel="100" else
		flash_tdo_p(5) when fl_sel="101" else 'Z';

--TCK
flash_tck_p(0) <= flash_tck(0) when fl_sel="110" else fl_tck_r when fl_sel="000" else '0';
flash_tck_p(1) <= flash_tck(1) when fl_sel="110" else fl_tck_r when fl_sel="001" else '0';
flash_tck_p(2) <= flash_tck(2) when fl_sel="110" else fl_tck_r when fl_sel="010" else '0';
flash_tck_p(3) <= flash_tck(3) when fl_sel="110" else fl_tck_r when fl_sel="011" else '0';
flash_tck_p(4) <= flash_tck(4) when fl_sel="110" else fl_tck_r when fl_sel="100" else '0';
flash_tck_p(5) <= flash_tck(5) when fl_sel="110" else fl_tck_r when fl_sel="101" else '0';


    
genprgmfpga: for igen in prgm_fpga'range generate
prgm_fpga_p (igen) <= '0' when prgm_fpga(igen)='1' 
                          or (evcnt_res='1' and ena_evres_prgm='1') 
                          else 'Z';
end generate;

--Registro las seņales JTAG porque tienen unos glitches enormes y no me verifica las memorias
process(reset,clk)
begin
	if reset='1' then
		fl_tdo_r <= '0';
		fl_tdi_r <= '0';
		fl_tms_r <= '0';
		fl_tck_r <= '0';	
	elsif clk'event and clk='1' then
		fl_tdo_r <= fl_tdo_aux;
		fl_tdi_r <= fl_tdi;
		fl_tms_r <= fl_tms;
		fl_tck_r <= fl_tck;	
	end if;
end process;

fl_tdo <= fl_tdo_r;

end arch;
	
