library ieee;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
use work.Types.all;

entity vme_bridge is

 -- polarities: when '1', the we have an inverting buffer in the way between cpld and VME connector
 generic ( 
    IrqPolarity : std_logic := '1';
    DtackPolarity : std_logic := '1'
	-- there is AC05 inverting buffer. FPGA has positive logic signal -> we need to invert.
	-- this is the way:
 );
  
  port (
    -- general part:
    nreset       : in  std_logic;        -- reset input, asynchronous
    clk         : in  std_logic;        -- 50MHz clk input
    -- vme64x part:
    xdata       : inout std_logic_vector(31 downto 0);  -- vme data bus
    xaddr       : in  std_logic_vector(23 downto 1);  -- vme address bus
    xam         : in  std_logic_vector(5 downto 0);  -- vme address modifier
    xbufdir     : out std_logic;        -- vme buffer direction register
    xiackoutn   : out std_logic;        -- interrupt acknowledge output
    xiackinn    : in  std_logic;        -- interrupt ack input
    xiackn      : in  std_logic;        -- interrupt acknowledge
    xas         : in  std_logic;        -- vme address strobe
    xlwordn     : in  std_logic;        -- lword of vme
    xdsn        : in  std_logic_vector(1 downto 0);  -- data strobes
    xwriten     : in  std_logic;        -- write from vme
    xdtack      : out std_logic;        -- vme data acknowledge
    xbufoen     : out std_logic_vector(1 downto 0);        -- vme buffers output enable
    xirq        : out std_logic;  -- interrupt requesters
    xsysreset   : in std_logic;        -- sysfail request out
    -- cpld only stuff:
    adrsel      : in  std_logic_vector(7 downto 0);  -- address selector headers
                                                        -- put on cpld header conn.

    -- test output:
    C_EXT    : out std_logic_vector(9 downto 1);  -- for testing. to be erased later on
    
	--reserved lines
	CPLD_CLK :  in  std_logic;  -- 212MHz clock
	RSV3 : in  std_logic;  
	CPU_INT : out std_logic;
	RVD1  : in  std_logic;
	RVD0  : in  std_logic;
	RVD11  : in  std_logic;
	RVD13  : in  std_logic;
	RVD12  : in  std_logic;
	PCI_CLK : out std_logic;
	BE : in  std_logic_vector(2 downto 0);
	
	
	Main_CK_enable : out std_logic;
	

    -- spi interface for accessing the EEPROM configuration memory + serial
    -- number chip
    spi_CS       : IN std_logic;           -- SPI slave select
    SPI_SI      : in  std_logic;           -- master in. We are master
    SPI_SO      : out std_logic;           -- master out
    SPI_SCK       : in std_logic;           -- we provide clock        

    
    -- fpga communication stuff:
    fpga_write  : out std_logic;        -- write strobe to fpga
    fpga_read   : out std_logic;        -- read strobe to fpga
    fpga_as     : out std_logic;        -- fpga address strobe (H=adr, L=dat)
    fpga_ad     : inout std_logic_vector(31 downto 0);  -- multiplexed address
                                                        -- data bus.

    fpga_drdy   : in std_logic;         -- when '1', the data are ready to be
                                        -- read from FPGA. This is sort of handshaking signal
    fpga_userirq : in std_logic;        -- '0' is interrupt request cycle
    fpga_irqdone: out std_logic;        -- informs fpga about the end of IRQ cycle

    AS_NCONFIG  : out std_logic;        -- active serial nconfig
    AS_NCE      : out std_logic;        -- activeserial chip enable for fpga
    AS_NSTATUS  : out std_logic;        -- activeserial nstatus
    AS_DCLK     : out std_logic;        -- activeserial clock
    AS_DATA     : in std_logic;      	-- activeserial output
    AS_ASDO     : out std_logic;        -- activeserial dataout
    AS_NCSO     : out std_logic;        -- activeserial ncso


	reconfig  : in std_logic; 
	CPLD_STAT : out std_logic;  -- LED on the front panel

    FPGA_RESET  : out std_logic);       -- reset fpga signal


    signal  spi_data_in : std_logic_vector(7 downto 0);
    signal  spi_data_out : std_logic_vector(7 downto 0);
    signal  spi_address_out : std_logic_vector(7 downto 0);
    signal  spi_write_en : std_logic;
    signal  spi_byte_sel : std_logic_vector(7 downto 0);




end vme_bridge;

architecture V1 of vme_bridge is
-------------------------------------------------------------------------------
-- component definitions:
-------------------------------------------------------------------------------
  
  -- generic vme interface
  component vme_decoder is
    generic (
      AddrWidth        : integer;
      BaseAddrWidth    : integer;
      DataWidth        : integer;
      DirSamePolarity  : std_logic;
      InterruptEn      : std_logic);
    port (
        ResetNA       : in std_logic;
        Clk           : in std_logic;
        VmeAddrA      : in std_logic_vector(AddrWidth-1 downto 1 );
        VmeAsNA       : in std_logic;
        VmeDs1NA      : in std_logic;
        VmeDs0NA      : in std_logic;
        VmeData       : inout std_logic_vector(DataWidth-1 downto 0 );
        VmeDir        : out std_logic;
        VmeDirFloat   : out std_logic;
        VmeBufOeN     : out std_logic;
        VmeWriteNA    : in std_logic;
        VmeLwordNA    : in std_logic;
        VmeIackNA     : in std_logic;
        IackOutNA     : out std_logic;
        IackInNA      : in std_logic;
        VmeIntReqN    : out std_logic;
        vmeDtackN     : out std_logic;
        ModuleAddr    : in std_logic_vector(BaseAddrWidth-1 downto 0 );
        VmeAmA        : in std_logic_vector(4 downto 0 );
	
        IntProcessed  : out std_logic;
        UserIntReqN   : in std_logic;
        UserBlocks    : in std_logic;

        -- spi interface for accessing the EEPROM configuration memory + serial
        -- number chip
        spi_CS       : in std_logic;          -- SPI slave select
        SPI_SI      : in  std_logic;           -- slave in
        SPI_SO      : out std_logic;           -- slaveout
        SPI_CLK       : in std_logic;         -- slave clock
--
--
        testoutput    : out std_logic;  -- for testing. to be erased later on

        -- fpga programming pins:
        fpga_nconfig  : out std_logic;  -- nconfig pulled low forces configuration
        fpga_nce      : out std_logic;  -- nce pulled high turns off the fpga
        as_asdo       : out   std_logic;       -- AS data out for the EPCS memory
        as_data       : in  std_logic;     -- AS data for the memory
        as_dclk       : out std_logic;       -- AD data for the memory
        as_ncs        : out std_logic;       -- chip select for activeserial memory

        -- we put the fpga memory interface signals:
        -- these are multiplexed communication
        fpga_write     : out   std_logic;   -- write strobe to fpga
        fpga_read      : out   std_logic;   -- read strobe to fpga
        fpga_as        : out   std_logic;   -- address/data strobe ('H' = data
        fpga_ad        : inout VLong;       -- multiplexed address/data bus
        fpga_drdy      : in    std_logic    -- '1' when data are ready to be taken
				);  

  end component vme_decoder;



  component spi_link
    port (
      clk         : in  STD_LOGIC;
      reset       : in  STD_LOGIC;
      SCK         : in  STD_LOGIC;
      SDI         : in  STD_LOGIC;
      SDO         : out STD_LOGIC;
      SCS         : in  std_logic;
      data_in     : in  STD_LOGIC_VECTOR (7 downto 0);
      data_out    : out STD_LOGIC_VECTOR(7 downto 0);
      address_out : out STD_LOGIC_VECTOR(7 downto 0);
      write_en    : out STD_LOGIC;
      byte_sel    : out STD_LOGIC_VECTOR (3 downto 0));
  end component;


  
-------------------------------------------------------------------------------
-- SIGNALS
-------------------------------------------------------------------------------
  signal clk1us : std_logic;            -- 1us clock enable derived from main clock
  signal interrupts : std_logic;  -- just placeholder for irqs
  signal ams : std_logic_vector(4 downto 0);  -- to make correct assignment
  signal dtack_in : std_logic;			-- copy of the signal to be able to negate it in the case

  signal IntProcessed     : std_logic;
  signal UserIntReqN      : std_logic;
  signal UserBlocks,
       	xbuf_O_en       : std_logic;
  signal reset : std_logic := '0';      -- reset - positive level
  
begin  -- V1
  -----------------------------------------------------------------------------
  -- asynchronous assignments:
  -----------------------------------------------------------------------------

  -- all others to high impedance:
  AS_NCSO <= 'Z';
  AS_NSTATUS <= 'Z';

  -- interrupt controller is always composed of 6 bits (not 7), so the
  -- most significant is '1' (as it's negative driven)
IrqPolarity0:  if IrqPolarity='0' generate
  xirq <= interrupts;
end generate IrqPolarity0;
IrqPolarity1:  if IrqPolarity='1' generate
  xirq <= not interrupts;
end generate IrqPolarity1;

DtackPolarity0:  if DtackPolarity='0' generate
  xdtack <= dtack_in;
end generate DtackPolarity0;
DtackPolarity1:  if DtackPolarity='1' generate
  xdtack <= not dtack_in;
end generate DtackPolarity1;


  -- do not block any VME actions:
  UserBlocks <= '0';

  -- vme interface doesn't use am2, so we don't take it into account
  ams(4) <= xam(5);
  ams(3) <= xam(4);
  ams(2) <= xam(3);
  ams(1) <= xam(1);
  ams(0) <= xam(0);

  -- fpga reset is for the moment driven by our reset:
  -- fpga reset in hiimp mode, otherwise we cannot do anything
  reset <= not nreset;               
  FPGA_RESET <= reset;
 

  -----------------------------------------------------------------------------
  -- VME component instances:
  -----------------------------------------------------------------------------

  -- NOTE: FOR THE MOMENT THE INTERRUPT ENABLE IS DISABLED!!!!!!

  -- VME interface
  Vme_intfce_1: vme_decoder
    generic map (
      AddrWidth        => 24,
      BaseAddrWidth    => 8,
      DataWidth        => 32,
      DirSamePolarity  => '0',          -- polarity of buffer direction pin
      InterruptEn      => '0')
    port map (
      -- reset and clock
      ResetNA          => reset,
      Clk              => clk,
      -- vme signals
        -- address
      VmeAddrA         => xaddr,
        -- address selectors:
      VmeAsNA          => xas,
      VmeDs1NA         => xdsn(1),
      VmeDs0NA         => xdsn(0),
      VmeLwordNA       => xlwordn,
      VmeWriteNA       => xwriten,
      vmeDtackN        => dtack_in,
      VmeAmA           => ams,
        -- data bus vme:
      VmeData          => xdata,
        -- buffers for VME bus:
      VmeDir           => xbufdir,
      VmeBufOeN        => xbuf_O_en ,
        -- interupt requesters:
      VmeIackNA        => xiackn,
      IackOutNA        => xiackoutn,
      IackInNA         => xiackinn,
      VmeIntReqN       => interrupts,
        -- module address is given by switches
      ModuleAddr       => adrsel,

        -- EEPROM SPI interface
      spi_CS          => spi_CS,
      SPI_SO         => SPI_SO,
      SPI_SI         => SPI_SI,
      SPI_CLK          => SPI_SCK,

        -- test output
      testoutput     => C_EXT(1),

        -- interrupt requests routed to fpga:
    
      UserIntReqN      => fpga_userirq,
      IntProcessed     => fpga_irqdone,
        -- programming pins of activeserial
      fpga_nconfig     => AS_NCONFIG,
      fpga_nce         => AS_NCE,
      as_data          => AS_DATA,
      as_dclk          => AS_DCLK,
      as_ncs           => AS_NCSO,
      as_asdo          => AS_ASDO,


        -- connection of cpld-fpga
      fpga_write     => fpga_write,
      fpga_read      => fpga_read,
      fpga_as        => fpga_as,
      fpga_ad        => fpga_ad,
      fpga_drdy      => fpga_drdy,
      
      UserBlocks       => UserBlocks);

                 spi_link_1: spi_link
                   port map (
                     clk         => clk,
                     reset       => reset,
                     SCK         => SPI_SCK,
                     SDI         => SPI_SI,
                     SDO         => SPI_SO ,
                     SCS         => spi_CS,
                     data_in     => spi_data_in,
                     data_out    => spi_data_out,
                     address_out => spi_address_out,
                     write_en    => spi_write_en,
                     byte_sel    => spi_byte_sel);


                 
-----------------------------------------------------------------------------
  -- I/O assignments:
-----------------------------------------------------------------------------



		xbufoen(0) <= xbuf_O_en ;
		xbufoen(1) <= xbuf_O_en ;



    C_EXT(9 downto 2) <= (others => 'Z'); 
    CPLD_STAT <= 'Z';
	--reserved lines
--	CPLD_CLK <= 'Z';  -- 212MHz clock
	--RSV3 <= 'Z';
	CPU_INT <= 'Z';
	--RVD1  <= 'Z';
	--RVD0  <= 'Z';
	--RVD11  <= 'Z';
	--RVD13  <= 'Z';
	--RVD12  <= 'Z';
	PCI_CLK <= 'Z';
	Main_CK_enable <= '1';

end V1;
