
--
-- Small Synchronous FIFO
--

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;



library UNISIM;
use UNISIM.vcomponents.all;

entity wrapper_sync_fifo is
  generic (
    width : natural := 32);
  port (
    clk     : in  std_logic;
    rst     : in  std_logic;
    wadv    : in  std_logic;
    wdata   : in  std_logic_vector(width-1 downto 0);
    wnfull  : out std_logic;
    wfull   : out std_logic;
    radv    : in  std_logic;
    rdata   : out std_logic_vector(width-1 downto 0);
    rdw_out : out std_logic_vector(width-1 downto 0);
    rempty  : out std_logic;
    rnempty : out std_logic
    );

end wrapper_sync_fifo;

architecture rtl of wrapper_sync_fifo is


  component RAM16X1D
    port (
      DPO   : out std_logic;
      SPO   : out std_logic;
      A0    : in  std_logic;
      A1    : in  std_logic;
      A2    : in  std_logic;
      A3    : in  std_logic;
      D     : in  std_logic;
      DPRA0 : in  std_logic;
      DPRA1 : in  std_logic;
      DPRA2 : in  std_logic;
      DPRA3 : in  std_logic;
      WCLK  : in  std_logic;
      WE    : in  std_logic);
  end component;

  signal rdw, wdw : std_logic_vector(width-1 downto 0);

  signal radv_q, wadv_q, empty, lempty : std_logic;

  signal full_r, empty_x, nempty : std_logic;

  signal waddr, raddr, raddr_p1, count : std_logic_vector(3 downto 0);

  
begin

  update_addr : process (clk, rst)
  begin
    if rst = '1' then
      waddr    <= (others => '0');
      raddr    <= (others => '0');
      raddr_p1 <= "0001";
      count    <= (others => '0');
    elsif clk'event and clk = '1' then
      if radv_q = '1' then
        raddr    <= raddr_p1;
        raddr_p1 <= raddr_p1+1;
      end if;
      if wadv_q = '1' then
        waddr <= waddr+1;
      end if;
      if radv_q = '1' and wadv_q = '0' then
        count <= count -1;
      else
        if wadv_q = '1' and radv_q = '0' then
          count <= count+1;
        end if;
      end if;
    end if;
  end process update_addr;


  empty  <= '1' when count = "0000" else '0';
  nempty <= '1' when count = "0001" else '0';
  full_r <= '1' when count = "1111" else '0';

  wnfull <= '1' when count(3 downto 2) = "11" else '0';

  radv_q <= radv and not empty;
  wadv_q <= wadv and not full_r;
  wfull  <= full_r;

  rempty  <= empty;
  rnempty <= nempty;


  r_op : process (clk, rst)
  begin
    if rst = '1' then
      rdata   <= (others => '0');
      lempty  <= '1';
      empty_x <= '1';
    elsif clk'event and clk = '1' then
      if radv = '1' then
        rdata <= rdw;
      end if;
      lempty  <= empty;
      empty_x <= nempty and radv;
    end if;
  end process r_op;

  gen_DPRAM : for i in 0 to width-1 generate
    ram_i : RAM16X1D
      port map (
        DPO   => rdw(i),
        A0    => waddr(0),
        A1    => waddr(1),
        A2    => waddr(2),
        A3    => waddr(3),
        D     => wdata(i),
        DPRA0 => raddr(0),
        DPRA1 => raddr(1),
        DPRA2 => raddr(2),
        DPRA3 => raddr(3),
        WCLK  => clk,
        WE    => wadv_q);
  end generate gen_DPRAM;

  rdw_out <= rdw;

end rtl;

--
-- plxdssm.vhd - PLX local bus direct slave state machine
--
-- Modules defined:
--
--     plxdssm           PLX local bus direct slave state machine
--
-- This state machine is designed to respond to direct slave transfers or
-- programmed DMA transfers, NOT demand mode DMA transfers.
--
-- One cycle of address decoding is permitted.
--

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;

entity plxdssm is
  port(
    clk       : in  std_logic;          -- Local bus clock
    rst       : in  std_logic;  -- Asynchronous reset, should reduce to FPGA global reset
    sr        : in  std_logic;  -- Synchronous reset (should never be asserted mid-burst)
    qlads     : in  std_logic;  -- LADS# signal qualified by address, FHOLDA and/or other decoding
    lblast    : in  std_logic;  -- Local bus LBLAST# signal, active high
    lwrite    : in  std_logic;          -- Local bus LWRITE signal, active high
    ld_oe     : out std_logic;  -- Output enable for local bus data pins
    lready    : out std_logic;  -- To local bus LREADY# signal, active high
    lready_oe : out std_logic;          -- Enable for local bus LREADY# signal
    lbterm    : out std_logic;  -- To local bus LBTERM# signal, active high
    lbterm_oe : out std_logic;  -- Enable for local bus LBTERM# signal, active high
    transfer  : out std_logic;          -- Data transfer on this clock edge
    decode    : out std_logic;  -- Application should do further address decoding
    write     : out std_logic;          -- 'lwrite' latched on 'qlads'
    ready     : in  std_logic;          -- Apply pulse when ready
    stop      : in  std_logic);         -- Pulse to terminate burst
end plxdssm;

architecture rtl of plxdssm is
  
  type   state_type is (s_idle, s_decode, s_wait, s_xfer);
  signal state, n_state           : state_type;
  signal i_transfer, n_transfer   : std_logic;
  signal i_lready, n_lready       : std_logic;
  signal i_lready_oe, n_lready_oe : std_logic;
  signal i_lbterm, n_lbterm       : std_logic;
  signal i_decode, n_decode       : std_logic;
  signal i_ld_oe, n_ld_oe         : std_logic;
  signal i_write, n_write         : std_logic;
  signal stopping, n_stopping     : std_logic;
  
begin

  transfer  <= i_transfer;
  lready    <= i_lready;
  lready_oe <= i_lready_oe;
  lbterm    <= i_lbterm;
  lbterm_oe <= i_lready_oe;
  decode    <= i_decode;
  ld_oe     <= i_ld_oe;
  write     <= i_write;

  state_transition : process(clk, rst)
  begin
    if rst = '1' then
      state       <= s_idle;
      i_transfer  <= '0';
      i_lready    <= '0';
      i_lready_oe <= '0';
      i_lbterm    <= '0';
      i_decode    <= '0';
      i_ld_oe     <= '0';
      i_write     <= '0';
      stopping    <= '0';
    elsif clk'event and clk = '1' then
      if sr = '1' then
        state       <= s_idle;
        i_transfer  <= '0';
        i_lready    <= '0';
        i_lready_oe <= '0';
        i_lbterm    <= '0';
        i_decode    <= '0';
        i_ld_oe     <= '0';
        i_write     <= '0';
        stopping    <= '0';
      else
        state       <= n_state;
        i_transfer  <= n_transfer;
        i_lready    <= n_lready;
        i_lready_oe <= n_lready_oe;
        i_lbterm    <= n_lbterm;
        i_decode    <= n_decode;
        i_ld_oe     <= n_ld_oe;
        i_write     <= n_write;
        stopping    <= n_stopping;
      end if;
    end if;
  end process state_transition;
  
  next_state : process(
    state,
    lblast,
    qlads,
    i_lbterm,
    lwrite,
    ready,
    stop,
    stopping,
    i_write)
  begin
    case state is
      when s_idle =>
        n_transfer  <= '0';
        n_lready    <= '0';
        n_lready_oe <= '0';
        n_lbterm    <= '0';
        n_ld_oe     <= '0';
        n_stopping  <= '0';
        if qlads = '1' then
          n_state  <= s_decode;
          n_decode <= '1';
          n_write  <= lwrite;
        else
          n_state  <= s_idle;
          n_decode <= '0';
          n_write  <= i_write;
        end if;
        
      when s_decode =>
        n_decode    <= '0';
        n_ld_oe     <= not i_write;
        n_lready_oe <= '1';
        n_write     <= i_write;
        if ready = '1' then
          n_state    <= s_xfer;
          n_lready   <= '1';
          n_lbterm   <= stop;
          n_transfer <= '1';
          n_stopping <= '0';
        else
          n_state    <= s_wait;
          n_lready   <= '0';
          n_lbterm   <= '0';
          n_transfer <= '0';
          n_stopping <= stop;
        end if;

      when s_wait =>
        n_decode    <= '0';
        n_ld_oe     <= not i_write;
        n_lready_oe <= '1';
        n_write     <= i_write;
        if ready = '1' then
          n_state    <= s_xfer;
          n_lready   <= '1';
          n_lbterm   <= stop or stopping;
          n_transfer <= '1';
          n_stopping <= '0';
        else
          n_state    <= s_wait;
          n_lready   <= '0';
          n_lbterm   <= '0';
          n_transfer <= '0';
          n_stopping <= stop or stopping;
        end if;
        
      when s_xfer =>
        n_decode    <= '0';
        n_lready_oe <= '1';
        n_stopping  <= '0';
        n_write     <= i_write;
        if lblast = '1' or i_lbterm = '1' then
          n_state    <= s_idle;
          n_lready   <= '0';
          n_lbterm   <= '0';
          n_transfer <= '0';
          n_ld_oe    <= '0';
        else
          n_state    <= s_xfer;
          n_lready   <= '1';
          n_lbterm   <= stop;
          n_transfer <= '1';
          n_ld_oe    <= not i_write;
        end if;
        
    end case;
  end process next_state;

end rtl;

--
-- 4 bit gray counter
--

library ieee;
use ieee.std_logic_1164.all;

entity gray4 is
  generic (
    initial_state : std_logic_vector(4 downto 0) := "00000");
  port (
    clk   : in  std_logic;
    rst   : in  std_logic;
    adv   : in  std_logic;
    count : out std_logic_vector(3 downto 0));

end gray4;

architecture rtl of gray4 is

  signal x, next_x         : std_logic_vector(3 downto 0);
  signal dummy, next_dummy : std_logic;
  
begin

  count <= x;

  clk_proc : process (clk, rst)
  begin
    if rst = '1' then
      x     <= initial_state(4 downto 1);
      dummy <= initial_state(0);
    elsif clk'event and clk = '1' then
      x     <= next_x;
      dummy <= next_dummy;
    end if;
  end process clk_proc;


  next_p : process (x, dummy, adv)
  begin
    if adv = '0' then
      next_x     <= x;
      next_dummy <= dummy;
    else
      next_dummy <= not dummy;
      next_x(0)  <= not dummy xor x(0);
      next_x(1)  <= (dummy and x(0)) xor x(1);
      next_x(2)  <= (dummy and x(1) and not x(0)) xor x(2);
      next_x(3)  <= (dummy and not x(1) and not x(0)) xor x(3);
    end if;
  end process next_p;
  

end rtl;


--
-- Small Asynchronous FIFO
--

library ieee;
use ieee.std_logic_1164.all;


-- synthesis translate_off
library UNISIM;
use UNISIM.all;
-- synthesis translate_on

entity async_fifo1 is
  generic (
    width : natural := 32);
  port (
    wclk    : in  std_logic;
    rst     : in  std_logic;
    wadv    : in  std_logic;
    wdata   : in  std_logic_vector(width-1 downto 0);
    wnfull  : out std_logic;
    wfull   : out std_logic;
    rclk    : in  std_logic;
    radv    : in  std_logic;
    rdata   : out std_logic_vector(width-1 downto 0);
    rdw_out : out std_logic_vector(width-1 downto 0);
    rempty  : out std_logic;
    rnempty : out std_logic
    );

end async_fifo1;

architecture rtl of async_fifo1 is

  component async_bram_fifo
    port (
      din        : in  std_logic_vector(31 downto 0);
      rd_clk     : in  std_logic;
      rd_en      : in  std_logic;
      rst        : in  std_logic;
      wr_clk     : in  std_logic;
      wr_en      : in  std_logic;
      dout       : out std_logic_vector(31 downto 0);
      empty      : out std_logic;
      full       : out std_logic;
      prog_empty : out std_logic;
      prog_full  : out std_logic);
  end component;

  component async_bram_fifo64
    port (
      din        : in  std_logic_vector(63 downto 0);
      rd_clk     : in  std_logic;
      rd_en      : in  std_logic;
      rst        : in  std_logic;
      wr_clk     : in  std_logic;
      wr_en      : in  std_logic;
      dout       : out std_logic_vector(63 downto 0);
      empty      : out std_logic;
      full       : out std_logic;
      prog_empty : out std_logic;
      prog_full  : out std_logic);
  end component;

  signal dinl, doutl      : std_logic_vector(31 downto 0);
  signal dinw, doutw      : std_logic_vector(63 downto 0);
  signal rdw_out_i        : std_logic_vector(width-1 downto 0);
  signal remptyl, remptyh : std_logic;
begin

  rdw_out <= rdw_out_i;

  reg_oip : process (rclk, rst)
  begin  -- process reg_oip
    if rst = '1' then                     -- asynchronous reset (active low)
      rdata <= (others => '0');
    elsif rclk'event and rclk = '1' then  -- rising clock edge
      if radv = '1' then
        rdata <= rdw_out_i;
      end if;
    end if;
  end process reg_oip;


  gen_1bram : if width < 33 generate

    dinl(width-1 downto 0) <= wdata;
    rdw_out_i              <= doutl(width-1 downto 0);

    abf0 : async_bram_fifo
      port map (
        din        => dinl,
        rd_clk     => rclk,
        rd_en      => radv,
        rst        => rst,
        wr_clk     => wclk,
        wr_en      => wadv,
        dout       => doutl,
        empty      => rempty,
        full       => wfull,
        prog_empty => rnempty,
        prog_full  => wnfull);

  end generate gen_1bram;

  gen_2bram : if width > 32 generate
    dinw(width-1 downto 0) <= wdata;
    rdw_out_i              <= doutw(width-1 downto 0);

    abf0 : async_bram_fifo64
      port map (
        din        => dinw,
        rd_clk     => rclk,
        rd_en      => radv,
        rst        => rst,
        wr_clk     => wclk,
        wr_en      => wadv,
        dout       => doutw,
        empty      => rempty,
        full       => wfull,
        prog_empty => rnempty,
        prog_full  => wnfull);

  end generate gen_2bram;
  


end rtl;




library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;

entity xlreqgrantmanager_ad is
  port (hw_req     : in  std_logic;
        sw_req     : out std_logic;
        hw_grant   : out std_logic;
        sw_grant   : in  std_logic;
        ram_active : in  std_logic;
        clk        : in  std_logic);
end xlreqgrantmanager_ad;
architecture structural of xlreqgrantmanager_ad is
  signal hw_req_int   : std_logic;
  signal hr_reg1      : std_logic;
  signal hr_reg1_en   : std_logic;
  signal hr_reg2      : std_logic;
  signal sw_req_int   : std_logic;
  signal sw_grant_int : std_logic;

  signal hw_grant_int  : std_logic;
  signal hwg_reg       : std_logic_vector(31 downto 0);
  signal hw_grant_pipe : std_logic;

begin
  sw_grant_int <= sw_grant;
  sw_req       <= sw_req_int;
  hr_reg1_en   <= not(hr_reg2);
  process (clk, hw_req)
  begin
    if (hw_req = '0') then
      hr_reg1 <= '0';
    elsif (clk'event and clk = '1') then
      if (hr_reg1_en = '1') then
        hr_reg1 <= '1';
      end if;
    end if;
  end process;
  process (clk)
  begin
    if (clk'event and clk = '1') then
      hr_reg2 <= hr_reg1;
    end if;
  end process;
  hw_req_int <= hw_req and hr_reg1;
  process (clk, hw_req_int)
  begin
    if (hw_req_int = '0') then
      sw_req_int <= '0';
    elsif (rising_edge(clk)) then
      if (sw_grant_int = '0') then
        sw_req_int <= '1';
      end if;
    end if;
  end process;
  process (clk, hw_req_int)
  begin
    if (hw_req_int = '0') then
      hw_grant_int <= '0';
    elsif (rising_edge(clk)) then
      if (sw_req_int = '1' and sw_grant_int = '1') then
        hw_grant_int <= '1';
      end if;
    end if;
  end process;

  process (clk)
  begin  -- process
    if clk'event and clk = '1' then     -- rising clock edge
      if ram_active = '0' then
        hw_grant <= hw_grant_int;
      end if;
    end if;
  end process;

  
end architecture structural;




library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;

library UNISIM;
use UNISIM.vcomponents.all;

library work;
use work.common_interface.all;

entity commonif is
  port(
    lclk       : in    std_logic;
    clk200_p   : in    std_logic;
    clk200_n   : in    std_logic;
    adcclk     : in    std_logic;
    lreseto_l  : in    std_logic;
    lwrite     : in    std_logic;
    lads_l     : in    std_logic;
    lblast_l   : in    std_logic;
    lbterm_o   : out   std_logic;
    lbterm_oe  : out   std_logic;
    lad_i      : in    std_logic_vector(63 downto 0);
    lad_o      : out   std_logic_vector(63 downto 0);
    lad_oe     : out   std_logic;
    lreadyi_o  : out   std_logic;
    lreadyi_oe : out   std_logic;
    lbe_l      : in    std_logic_vector(7 downto 0);
    fholda     : in    std_logic;
    finti_l    : out   std_logic;
    -- DDRII Memory Banks
    DDR0_RAS_N : out   std_logic;
    DDR0_CAS_N : out   std_logic;
    DDR0_WE_N  : out   std_logic;
    DDR0_ODT   : out   std_logic;
    DDR0_CKE   : out   std_logic;
    DDR0_CS_N  : out   std_logic;
    DDR0_DQ    : inout std_logic_vector(31 downto 0);
    DDR0_DQS   : inout std_logic_vector(3 downto 0);
    DDR0_DQS_N : inout std_logic_vector(3 downto 0);
    DDR0_DM    : out   std_logic_vector(3 downto 0);
    DDR0_CK    : out   std_logic_vector(1 downto 0);
    DDR0_CK_N  : out   std_logic_vector(1 downto 0);
    DDR0_BA    : out   std_logic_vector(2 downto 0);
    DDR0_A     : out   std_logic_vector(12 downto 0);
    DDR1_RAS_N : out   std_logic;
    DDR1_CAS_N : out   std_logic;
    DDR1_WE_N  : out   std_logic;
    DDR1_ODT   : out   std_logic;
    DDR1_CKE   : out   std_logic;
    DDR1_CS_N  : out   std_logic;
    DDR1_DQ    : inout std_logic_vector(31 downto 0);
    DDR1_DQS   : inout std_logic_vector(3 downto 0);
    DDR1_DQS_N : inout std_logic_vector(3 downto 0);
    DDR1_DM    : out   std_logic_vector(3 downto 0);
    DDR1_CK    : out   std_logic_vector(1 downto 0);
    DDR1_CK_N  : out   std_logic_vector(1 downto 0);
    DDR1_BA    : out   std_logic_vector(2 downto 0);
    DDR1_A     : out   std_logic_vector(12 downto 0);
    DDR2_RAS_N : out   std_logic;
    DDR2_CAS_N : out   std_logic;
    DDR2_WE_N  : out   std_logic;
    DDR2_ODT   : out   std_logic;
    DDR2_CKE   : out   std_logic;
    DDR2_CS_N  : out   std_logic;
    DDR2_DQ    : inout std_logic_vector(31 downto 0);
    DDR2_DQS   : inout std_logic_vector(3 downto 0);
    DDR2_DQS_N : inout std_logic_vector(3 downto 0);
    DDR2_DM    : out   std_logic_vector(3 downto 0);
    DDR2_CK    : out   std_logic_vector(1 downto 0);
    DDR2_CK_N  : out   std_logic_vector(1 downto 0);
    DDR2_BA    : out   std_logic_vector(2 downto 0);
    DDR2_A     : out   std_logic_vector(12 downto 0);
    DDR3_RAS_N : out   std_logic;
    DDR3_CAS_N : out   std_logic;
    DDR3_WE_N  : out   std_logic;
    DDR3_ODT   : out   std_logic;
    DDR3_CKE   : out   std_logic;
    DDR3_CS_N  : out   std_logic;
    DDR3_DQ    : inout std_logic_vector(31 downto 0);
    DDR3_DQS   : inout std_logic_vector(3 downto 0);
    DDR3_DQS_N : inout std_logic_vector(3 downto 0);
    DDR3_DM    : out   std_logic_vector(3 downto 0);
    DDR3_CK    : out   std_logic_vector(1 downto 0);
    DDR3_CK_N  : out   std_logic_vector(1 downto 0);
    DDR3_BA    : out   std_logic_vector(2 downto 0);
    DDR3_A     : out   std_logic_vector(12 downto 0);
    debug      : out   std_Logic_vector(63 downto 0);
    -- Interface to Synth
    synth_cntrl : out std_logic_vector(15 downto 0);
    synth_strb  : out std_logic_vector(3 downto 0);
    synth_status : in std_logic_vector(31 downto 0);
    synth_rst  : out std_logic;
    -- Interface to User Top Level
    clk        : out   std_logic;
    rst        : out   std_logic;
    system_in  : out   std_logic_vector(system_width-1 downto 0);
    system_out : in    std_logic_vector(system_width-1 downto 0));
end commonif;

architecture mixed of commonif is


  constant number_of_aurorae : integer := 0;
  constant number_of_dram    : integer := 4;

  signal rst_i    : std_logic;
  signal rst_i_bg : std_logic;
  signal blast_i  : std_logic;
  signal ads_i    : std_logic;
  signal qlads    : std_logic;
  signal write_i  : std_logic;

  signal ds_xfer   : std_logic;
  signal ds_decode : std_logic;
  signal ld_o      : std_logic_vector(63 downto 0);
  signal ld_i      : std_logic_vector(63 downto 0);
  signal ld_oe     : std_logic;
  signal la_i      : std_logic_vector(23 downto 2);
  signal be_i      : std_logic_vector(7 downto 0);

  signal la_q    : std_logic_vector(23 downto 2);
  signal write_q : std_logic;

  signal addr_reg : std_logic_vector(31 downto 0);


  signal oe_user  : std_logic;
  signal oe_imem  : std_logic;
  signal imem_reg : std_logic_vector(31 downto 0);


  signal bram_out, bram_out1 : std_logic_vector(bram_width-1 downto 0);
  signal zeros               : std_logic_vector(3 downto 0);
  signal ds_write            : std_logic;

  signal logic0 : std_logic;
  signal logic1 : std_logic;

  signal burst_active : std_logic;
  signal ds_ready     : std_logic;
  signal ds_ready_rd  : std_logic;
  signal ds_ready_wr  : std_logic;
  signal ds_stop      : std_logic;

  signal lclk0       : std_logic;
  signal clk0, mclk0 : std_logic;
  signal user_reg : std_logic_vector(31 downto 0);

  component plxdssm
    port(
      clk       : in  std_logic;
      rst       : in  std_logic;
      sr        : in  std_logic;
      qlads     : in  std_logic;
      lblast    : in  std_logic;
      lwrite    : in  std_logic;
      ld_oe     : out std_logic;
      lready    : out std_logic;
      lready_oe : out std_logic;
      lbterm    : out std_logic;
      lbterm_oe : out std_logic;
      transfer  : out std_logic;
      decode    : out std_logic;
      write     : out std_logic;
      ready     : in  std_logic;
      stop      : in  std_logic);
  end component;



  component dram2if
      generic (
    chipscope : boolean := false);
  port (
    lclk              : in    std_logic;
    rst               : in    std_logic;
    sysclk            : in    std_logic;
    -- SYSGEN Port Interface
    dram_out          : in    extmem_type;
    dram_in           : out   extmem_type;
    -- Local Bus Interface
    ld_i              : in    std_logic_vector(63 downto 0);
    ld_o              : out   std_logic_vector(63 downto 0);
    la_q              : in    std_logic_vector(27 downto 0);
    lwrite            : in    std_logic;
    lblast            : in    std_logic;
    lbterm            : in    std_logic;
    ds_xfer           : in    std_logic;
    lads              : in    std_logic;
    ready             : out   std_logic;
    stop              : out   std_logic;
    lb_request        : out   std_logic;
    lb_grant          : in    std_logic;
    lb_rskip          : in    std_logic_vector(4 downto 0);
    lb_roffset        : in    std_logic_vector(4 downto 0);
    status            : out   std_logic_vector(31 downto 0);
    debug : out std_Logic_vector(63 downto 0);
    -- Connections to DDRII Clocking and Infrastructure modules
    clk_0             : in    std_logic;
    clk_90            : in    std_logic;
    CNTL_CLK_ID1 : in std_logic;
    CNTL_CLK_ID2 : in std_logic;
    CNTL_CLK_ID3 : in std_logic;
    CNTL_CLK_ID4 : in std_logic; 
    sys_rst           : in    std_logic;
    sys_rst90         : in    std_logic;
    SYS_RST_ID : in std_logic;
    idelay_ctrl_rdy   : in    std_logic;
    online            : out   std_Logic;
    -- RAM Interface
    DDR2_RAS_N        : out   std_logic;
    DDR2_CAS_N        : out   std_logic;
    DDR2_WE_N         : out   std_logic;
    DDR2_ODT          : out   std_logic;
    DDR2_CKE          : out   std_logic;
    DDR2_CS_N         : out   std_logic;
    DDR2_DQ           : inout std_logic_vector(31 downto 0);
    DDR2_DQS          : inout std_logic_vector(3 downto 0);
    DDR2_DQS_N        : inout std_logic_vector(3 downto 0);
    DDR2_DM           : out   std_logic_vector(3 downto 0);
    DDR2_CK           : out   std_logic_vector(1 downto 0);
    DDR2_CK_N         : out   std_logic_vector(1 downto 0);
    DDR2_BA           : out   std_logic_vector(2 downto 0);
    DDR2_A            : out   std_logic_vector(12 downto 0)
    );
  end component;

  component mem_interface_infrastructure_DirectClk
    port (
          SYS_CLK           : in std_logic;
          CLK200            : in std_logic;
          SYS_RESET_INn     : in std_logic;
          CLK               : out std_logic;
          CLK90             : out std_logic;
          CLK_ID1          : out std_logic;
          CLK_ID2         : out std_logic;
          CLK_ID3       : out std_logic;
          CLK_ID4       : out std_logic;
          idelay_ctrl_rdy   : out std_logic;
          LOCKED            : out std_logic_vector(1 downto 0);
          sys_rst           : out std_logic;
          sys_rst_90        : out std_logic;
          sys_rst_id        : out std_logic
               );
    end component;
  


  component ddrii_if_idelay_ctrl
    port (
      CLK200     : in  std_logic;
      RESET      : in  std_logic;
      RDY_STATUS : out std_logic
      );
  end component;



  signal mem_reg                : std_logic_vector(3 downto 0);
  signal mem_reg_decode         : std_logic_vector(5 downto 0);
  signal mem_status             : std_logic_vector(7 downto 0);
  signal ext_mem                : std_logic;
  signal oe_mem                 : std_logic;
  signal qlads_mem, ds_xfer_mem : std_logic_vector(5 downto 0);
  signal mem_addr               : std_logic_vector(21 downto 0);
  signal mem_addr_ddr           : std_logic_vector(27 downto 0);



  signal mem_out, mem_out0, mem_out1, mem_out2, mem_out3, mem_out4, mem_out5 : std_logic_vector(63 downto 0);
  signal ds_ready_mem, ready0, ready1, ready2, ready3, ready4, ready5        : std_logic;
  signal mem_gnt, mem_gnt_trig, mem_gnt_auto                                 : std_logic_vector(7 downto 0);

  signal clk180, mclk, mclkb : std_logic;



  signal refclk        : std_logic;
  signal refclk_fb     : std_logic;
  signal clk0b         : std_logic;
  signal clk_i, lclk_i : std_logic;

  signal dram0_stop, dram1_stop, dram2_stop, dram3_stop : std_logic;

  signal locked : std_logic_vector(3 downto 0);

  signal ld_reg : std_logic_vector(31 downto 0);
  signal oe_reg : std_logic;

  signal interrupt : std_logic;

  signal dcm_rst1, dcm_rst2_1, dcm_rst2_2, dcm_rst2_3, dcm_rst2_0 : std_logic;
  signal dcm_rst_count1     : std_logic_vector(8 downto 0);
  signal dcm_rst_count2     : std_logic_vector(8 downto 0);
  signal ld_i_mem           : std_logic_vector(31 downto 0);

  signal addr_i : std_logic_vector(24 downto 0);

  signal dram0_in, dram0_out : extmem_type;
  signal dram1_in, dram1_out : extmem_type;
  signal dram2_in, dram2_out : extmem_type;
  signal dram3_in, dram3_out : extmem_type;

  signal ctrl_bus_ivec   : std_logic_vector(ctrl_bus_width-1 downto 0);
  signal status_bus_ivec : std_logic_vector(status_bus_width-1 downto 0);
  signal irq_bus_ivec    : std_logic_vector(interrupt_bus_width-1 downto 0);
  signal bram_bus_ivec   : std_logic_vector(bram_bus_width-1 downto 0);
  signal locallinks_ivec : std_logic_vector(4*locallink_type_width-1 downto 0);
  signal extrams_ivec    : std_logic_vector(6*extmem_type_width-1 downto 0);

  signal ctrl_bus_ovec   : std_logic_vector(ctrl_bus_width-1 downto 0);
  signal status_bus_ovec : std_logic_vector(status_bus_width-1 downto 0);
  signal irq_bus_ovec    : std_logic_vector(interrupt_bus_width-1 downto 0);
  signal bram_bus_ovec   : std_logic_vector(bram_bus_width-1 downto 0);
  signal locallinks_ovec : std_logic_vector(4*locallink_type_width-1 downto 0);
  signal extrams_ovec    : std_logic_vector(6*extmem_type_width-1 downto 0);
  signal lclk_dummy      : std_logic;

  signal ctrl_bus_in                   : ctrl_bus_type;
  signal status_bus_in, status_bus_out : status_bus_type;
  signal irq_bus_in, irq_bus_out       : interrupt_bus_type;
  signal bram_bus_in, bram_bus_out     : bram_bus_type;

  -- DDR2 Infrasturcture

  signal idelay_ctrl_rdy                               : std_logic;
  signal sys_rst0,sys_rst1,sys_rst2,sys_rst3           : std_logic;
  signal sys_rst90_0, sys_rst90_1, sys_rst90_2, sys_rst90_3 : std_logic;
  signal sys_rst_i                                       : std_logic;
  signal sys_rst90_i                                     : std_logic;
  signal sys_rst_ref_clk_1                             : std_logic;
  signal clk_0, clk_90, clk_200                        : std_logic;
  signal clkdiv_0, clkdiv_90, clkdiv_mux0, clkdiv_mux1 : std_logic;
  signal sys_clk,sys_clk_i,ref_clk200_in,clk200_bufg_out,ref_clk200 : std_logic;
      
  signal ddr2_CLK_ID1    : std_logic;
  signal ddr2_CLK_ID2   : std_logic;
  signal ddr2_CLK_ID3      : std_logic;
  signal ddr2_CLK_ID4      : std_logic;
  signal sys_rst_id       : std_logic;
  
  signal usrclk_i, usrclk2, usrclk_2xi : std_logic;

  signal usrclk : std_logic;

 



  signal mem_rst       : std_logic;
  signal mem_rst_n     : std_logic;
  signal mem_rst_count : std_logic_vector(3 downto 0);

  signal lb_rskip_reg,lb_roffset_reg : std_logic_vector(4 downto 0);

  signal mem_online : std_logic_vector(5 downto 0);
  signal reset_reg : std_Logic_vector(31 downto 0);

  signal bram_bus_out_flush : std_logic;
  signal ds_xfer_reg : std_logic;
  signal bram_bus_qv_reg : std_logic;
  
  signal ld32_reg : std_logic_vector(31 downto 0);

  signal lbterm : std_logic;


  signal mem_overflow0 : std_logic_vector(31 downto 0);
  signal mem_overflow1 : std_logic_vector(31 downto 0);
  signal mem_overflow2 : std_logic_vector(31 downto 0);
  signal mem_overflow3 : std_logic_vector(31 downto 0);

  signal mem_overflow_reg0 : std_logic_vector(31 downto 0);
  signal mem_overflow_reg1 : std_logic_vector(31 downto 0);
  signal mem_overflow_reg2 : std_logic_vector(31 downto 0);
  signal mem_overflow_reg3 : std_logic_vector(31 downto 0);

  -- Force Register Duplication to be used for LA_Q
  attribute max_fanout : integer;
  attribute max_fanout of la_q : signal is 16;
  
  
begin

  -- Split output system signals and convert data types
  
  split0 : split_system_signal(
    system     => system_out,
    lclk       => lclk_dummy,
    ctrl_bus   => ctrl_bus_ovec,
    status_bus => status_bus_ovec,
    irq_bus    => irq_bus_ovec,
    bram_bus   => bram_bus_ovec,
    locallinks => locallinks_ovec,
    extrams    => extrams_ovec);

  status_bus_out <= slv_to_status_bus(status_bus_ovec);
  irq_bus_out    <= slv_to_irq_bus(irq_bus_ovec);
  bram_bus_out   <= slv_to_bram_bus(bram_bus_ovec);
  dram0_out      <= slv_to_extmem_type(extrams_ovec(extmem_type_width-1 downto 0));
  dram1_out      <= slv_to_extmem_type(extrams_ovec(2*extmem_type_width-1 downto extmem_type_width));
  dram2_out      <= slv_to_extmem_type(extrams_ovec(3*extmem_type_width-1 downto 2*extmem_type_width));
  dram3_out      <= slv_to_extmem_type(extrams_ovec(4*extmem_type_width-1 downto 3*extmem_type_width));




  -- Merge signals into system inputs
  
  merge0 : build_system_signal (
    system     => system_in,
    lclk       => lclk0,
    ctrl_bus   => ctrl_bus_ivec,
    status_bus => status_bus_ivec,
    irq_bus    => irq_bus_ivec,
    bram_bus   => bram_bus_ivec,
    locallinks => locallinks_ivec,
    extrams    => extrams_ivec);

  ctrl_bus_ivec   <= ctrl_bus_to_slv(ctrl_bus_in);
  status_bus_ivec <= status_bus_to_slv(status_bus_in);
  irq_bus_ivec    <= irq_bus_to_slv(irq_bus_in);
  bram_bus_ivec   <= bram_bus_to_slv(bram_bus_in);
  extrams_ivec    <= CONV_STD_LOGIC_VECTOR(0, extmem_type_width*2) & extmem_type_to_slv(dram3_in) & extmem_type_to_slv(dram2_in) & extmem_type_to_slv(dram1_in) & extmem_type_to_slv(dram0_in);

  locallinks_ivec <= (others => '0');


  logic0 <= '0';
  logic1 <= '1';

  --
  -- Convert the inputs to active high.
  --    
  rst_i   <= not lreseto_l;
  rst     <= rst_i;
  blast_i <= not lblast_l;
  ads_i   <= not lads_l;
  write_i <= lwrite;
  la_i    <= lad_i(23 downto 2);
  ld_i    <= lad_i;
  lad_o   <= ld_o;
  lad_oe  <= ld_oe;
  be_i <= not lbe_l;

  clk <= SYS_CLK;

  lclk_bufg : BUFG
    port map (
      I => lclk_i,
      O => lclk0);


 

  dcm0 : DCM
    generic map (
      clkfx_multiply => 3,
      clkfx_divide   => 1)
    port map (
      clkin    => lclk,
      clkfb    => lclk0,
      dssen    => '0',
      psincdec => '0',
      psen     => '0',
      psclk    => '0',
      rst      => rst_i,
      locked   => locked(0),
      clk0     => lclk_i,
      clkfx    => mclk,
      clkfx180 => mclkb);


  
  mclk0_bufg : BUFG
    port map (
      I => mclk,
      O => clk0);


  clk_i <= SYS_CLK;

  -- Generating Reset for DDR Memory Controllers
  -- DCM 2 now removed from design
  dcm_reset_block2 : process (lclk0, rst_i)
  begin  -- process dcm_reset_block2
    if rst_i = '1' then
      dcm_rst2_0       <= '1';
      dcm_rst2_1       <= '1';
      dcm_rst2_2       <= '1';
      dcm_rst2_3       <= '1';
      dcm_rst_count2 <= (others => '1');
      mem_rst        <= '0';
      mem_rst_count  <= (others => '1');
    elsif lclk0'event and lclk0 = '1' then  -- rising clock edge
      dcm_rst2_0 <= OR_reduce(dcm_rst_count2);
      dcm_rst2_1 <= OR_reduce(dcm_rst_count2);
      dcm_rst2_2 <= OR_reduce(dcm_rst_count2);
      dcm_rst2_3 <= OR_reduce(dcm_rst_count2);
      if locked(0) = '0' or reset_reg(0) = '1' then
        dcm_rst_count2 <= (others => '1');
      elsif OR_reduce(dcm_rst_count2) = '1' then
        dcm_rst_count2 <= dcm_rst_count2-1;
      end if;
      mem_rst <= not OR_reduce(mem_rst_count);
      if locked(0) = '0' or reset_reg(1) = '1' then
        mem_rst_count <= (others => '1');
      elsif OR_reduce(mem_rst_count) = '1' then
        mem_rst_count <= mem_rst_count-1;
      end if;
    end if;
  end process dcm_reset_block2;



  --
  -- Decode the address of the FPGA which is the space when LA[23] is 0
  --
  qlads <= ads_i and not la_i(23) and not fholda;

  --
  -- Latch the local bus address on the 'lads_l' pulse.
  --
  latch_addr : process(rst_i, lclk0)
  begin
    if rst_i = '1' then
      la_q         <= (others => '0');
      burst_active <= '0';
      ds_ready_rd  <= '0';
      bram_bus_qv_reg <= '0';
      bram_bus_out_flush <= '0';
      ds_xfer_reg <= '0';
    elsif lclk0'event and lclk0 = '1' then
      if ads_i = '1' then
        la_q <= la_i;
      elsif ds_xfer = '1' or burst_active = '1' then  --or (la_q(21) = '1' and ds_decode = '1' and lwrite = '0')
        la_q(20 downto 2) <= la_q(20 downto 2)+2;
      end if;
      if ds_decode = '1' and la_q(21) = '1' and lwrite = '0' then
        burst_active <= '1';
      elsif blast_i = '1' or ds_stop = '1' or (la_q(21) = '0') then
        burst_active <= '0';
      end if;
      ds_ready_rd <= (bram_bus_out.qv and not ext_mem and not bram_bus_out_flush) or (not la_q(21) and not burst_active and not ads_i);
      bram_bus_qv_reg <= bram_bus_out.qv;
      ds_xfer_reg <= ds_xfer;
      if ds_xfer = '0' and ds_xfer_reg = '1' and bram_bus_out.qv = '1' then
        bram_bus_out_flush <= '1';
      elsif bram_bus_qv_reg = '1' and bram_bus_out.qv = '0' then
        bram_bus_out_flush <= '0';
      end if;
    end if;
  end process;

  ds_ready_wr <= ds_write and ds_decode and (not (la_q(21) and ext_mem));
  ds_ready    <= ds_ready_rd or ds_ready_wr or ds_ready_mem;
  ds_stop     <= dram0_stop or dram1_stop or dram2_stop or dram3_stop or not la_q(21);


  --
  -- If the current cycle is a write, update the register
  --            
  update_reg : process(lclk0, rst_i)
    variable i : integer;
  begin
    if rst_i = '1' then
      addr_reg       <= (others => '0');
      irq_bus_in.ier <= (others => '0');
      irq_bus_in.isr <= (others => '0');
      mem_gnt_trig   <= (others => '0');
      mem_gnt_auto   <= (others => '1');
      mem_reg        <= (others => '0');
      imem_reg       <= (others => '0');
      mem_reg_decode <= (others => '0');
      lb_rskip_reg <= "00001";
      lb_roffset_reg <= (others => '0');
      reset_reg <= (others => '0');
      synth_cntrl <= (others => '0');
      synth_strb <= (others => '0');
      synth_rst <= '0';
    elsif lclk0'event and lclk0 = '1' then
      reset_reg <= (others => '0');
      if ds_xfer = '1' and ds_write = '1' then
        if la_q(11) = '0' and la_q(21) = '0' then
          if la_q(7 downto 3) = "00000" then
            imem_reg <= ld_i(31 downto 0);
          end if;
          if la_q(7 downto 3) = "00001" then
            reset_reg <= ld_i(31 downto 0);
          end if;
          if la_q(7 downto 3) = "00010" then
            addr_reg <= ld_i(31 downto 0);
          end if;
          if la_q(7 downto 3) = "00011" then
            mem_reg <= ld_i(3 downto 0);
          end if;
          if la_q(7 downto 3) = "00110" then
            lb_rskip_reg <= ld_i(4 downto 0);
          end if;
          if la_q(7 downto 3) = "00111" then
            lb_roffset_reg <= ld_i(4 downto 0);
          end if;
          if la_q(7 downto 3) = "00100" then
            irq_bus_in.ier <= ld_i(reg_width-1 downto 0);
          end if;
          if la_q(7 downto 3) = "00101" then
            irq_bus_in.isr <= ld_i(reg_width-1 downto 0);
          end if;
          if la_q(7 downto 3) = "01000" then
            mem_gnt_trig(0) <= ld_i(0);
            mem_gnt_auto(0) <= ld_i(1);
          end if;
          if la_q(7 downto 3) = "01001" then
            mem_gnt_trig(1) <= ld_i(0);
            mem_gnt_auto(1) <= ld_i(1);
          end if;
          if la_q(7 downto 3) = "01010" then
            mem_gnt_trig(2) <= ld_i(0);
            mem_gnt_auto(2) <= ld_i(1);
          end if;
          if la_q(7 downto 3) = "01011" then
            mem_gnt_trig(3) <= ld_i(0);
            mem_gnt_auto(3) <= ld_i(1);
          end if;
          if la_q(7 downto 3) = "01100" then
            mem_gnt_trig(4) <= ld_i(0);
            mem_gnt_auto(4) <= ld_i(1);
          end if;
          if la_q(7 downto 3) = "01101" then
            mem_gnt_trig(5) <= ld_i(0);
            mem_gnt_auto(5) <= ld_i(1);
          end if;
          if la_q(7 downto 3) = "10000" then
            synth_cntrl <= ld_i(15 downto 0);
          end if;
          if la_q(7 downto 3) = "10001" then
            synth_strb <= ld_i(3 downto 0);
          end if;
          if la_q(7 downto 3) = "10010" then
            synth_rst <= ld_i(0);
          end if;
        end if;
      end if;

      if mem_reg(3) = '1' then
        for i in 0 to 5 loop
          if mem_reg(2 downto 0) = CONV_STD_LOGIC_VECTOR(i, 3) then
            mem_reg_decode(i) <= '1';
          else
            mem_reg_decode(i) <= '0';
          end if;
        end loop;  -- i
      else
        for i in 0 to 5 loop
          mem_reg_decode(i) <= '0';
        end loop;
      end if;
 
    end if;
  end process update_reg;

  ext_mem <= mem_reg(3);

  --
  -- Generate the 'oe_reg*' signals, for enabling registers onto
  -- the internal data bus.
  --
  generate_oe_reg : process(rst_i, lclk0)
  begin
    if rst_i = '1' then
      oe_user   <= '0';
      oe_mem    <= '0';
      oe_imem   <= '0';
      oe_reg    <= '0';
      ld_reg    <= (others => '0');
      interrupt <= '0';
      mem_overflow_reg0 <= (others => '0');
      mem_overflow_reg1 <= (others => '0');
      mem_overflow_reg2 <= (others => '0');
      mem_overflow_reg3 <= (others => '0');
    elsif lclk0'event and lclk0 = '1' then
      interrupt <= (OR_reduce(irq_bus_out.isr));
      mem_overflow_reg0 <= mem_overflow0;
      mem_overflow_reg1 <= mem_overflow1;
      mem_overflow_reg2 <= mem_overflow2;
      mem_overflow_reg3 <= mem_overflow3;
      if ds_xfer = '1' and blast_i = '1' then
        oe_user <= '0';
        oe_mem  <= '0';
        oe_imem <= '0';
        oe_reg  <= '0';
      else
        if ds_decode = '1' and ds_write = '0' then
          if la_q(11) = '0' and la_q(21) = '0' then
            oe_reg <= '1';
            if la_q(7 downto 3) = "00000" then
              ld_reg <= imem_reg;
            end if;
            if la_q(7 downto 3) = "00010" then
              ld_reg <= addr_reg;
            end if;
            if la_q(7 downto 3) = "00011" then
              ld_reg <= X"00" & mem_status & mem_gnt & "0000" & mem_reg;
            end if;
            if la_q(7 downto 3) = "00001" then
              ld_reg <= EXT(mem_online & locked, 32);
            end if;
            if la_q(7 downto 3) = "00100" then
              ld_reg <= irq_bus_in.ier;
            end if;
            if la_q(7 downto 3) = "00101" then
              ld_reg <= irq_bus_out.isr;
            end if;
            if la_q(7 downto 3) = "00110" then
              ld_reg <= EXT(lb_rskip_reg,32);
            end if;
            if la_q(7 downto 3) = "00111" then
              ld_reg <= EXT(lb_roffset_reg,32);
            end if;
            if la_q(7 downto 3) = "01000" then
              ld_reg <= mem_overflow_reg0;
            end if;
            if la_q(7 downto 3) = "01001" then
              ld_reg <= mem_overflow_reg1;
            end if;
            if la_q(7 downto 3) = "01010" then
              ld_reg <= mem_overflow_reg2;
            end if;
            if la_q(7 downto 3) = "01011" then
              ld_reg <= mem_overflow_reg3;
            end if;
            if la_q(7 downto 3) = "10000" then
              ld_reg <= synth_status;
            end if;
            
            
            
          else
            oe_reg <= '0';
          end if;
          oe_user <= la_q(11) and not la_q(21);
          oe_imem <= la_q(21) and not ext_mem;
          oe_mem  <= la_q(21) and ext_mem;
        end if;
      end if;
      user_reg <= status_bus_out.data;
    end if;
  end process generate_oe_reg;

  finti_l <= not interrupt;

  ld_o(63 downto 32) <= bram_out(63 downto 32) when oe_imem = '1' else mem_out(63 downto 32);
  ld_o(31 downto 0)  <= ld_reg                 when oe_reg = '1'  else user_reg when oe_user = '1' else bram_out(31 downto 0) when oe_imem = '1' else mem_out(31 downto 0);

  dssm : plxdssm
    port map(
      clk       => lclk0,
      rst       => rst_i,
      sr        => logic0,
      qlads     => qlads,
      lblast    => blast_i,
      lwrite    => lwrite,
      ld_oe     => ld_oe,
      lready    => lreadyi_o,
      lready_oe => lreadyi_oe,
      lbterm    => lbterm,
      lbterm_oe => lbterm_oe,
      transfer  => ds_xfer,
      decode    => ds_decode,
      write     => ds_write,
      ready     => ds_ready,
      stop      => ds_stop);

  lbterm_o <= lbterm;
  
  gen_addr : process (la_q, addr_reg)
  begin  -- process gen_addr
    if la_q(21) = '0' then
      addr_i <= EXT(la_q(10 downto 2), 25);
    else
      addr_i <= addr_reg(24 downto 19) & la_q(20 downto 2);
    end if;
  end process gen_addr;



  -- User Application Control registers
  user_ctrl : process (lclk0, rst_i)
  begin  -- process user_ctrl
    if rst_i = '1' then                     -- asynchronous reset (active low)
      ctrl_bus_in.data <= (others => '0');
      ctrl_bus_in.addr <= (others => '0');
      ctrl_bus_in.wstb <= '0';
    elsif lclk0'event and lclk0 = '1' then  -- rising clock edge
      ctrl_bus_in.data <= ld_i(reg_width-1 downto 0);
      ctrl_bus_in.addr <= la_q(reg_addr_width+2 downto 3);
      ctrl_bus_in.wstb <= ds_xfer and ds_write and la_q(11) and not la_q(21);
    end if;
  end process user_ctrl;

  -- User Application Status registers
  status_bus_in.addr <= la_q(reg_addr_width+2 downto 3);

  -- User Application BRAM
  bram_bus_in.data <= ld_i(bram_width-1 downto 0) when be_i(3) = '1' else ld_i(bram_width-1 downto 32) & ld32_reg;
  bram_bus_in.addr <= la_q(bram_addr_width+2 downto 3);
  bram_bus_in.id   <= imem_reg(bram_id_width-1 downto 0);
  bram_bus_in.wstb <= ds_xfer and ds_write and la_q(21) and not ext_mem and be_i(7);
  bram_bus_in.rstb <= burst_active and la_q(21) and not ext_mem;
  bram_bus_in.qv <= '0';
  process (lclk0)
  begin
    if lclk0'event and lclk0 = '1' then
      bram_out1 <= bram_bus_out.q;
      bram_out  <= bram_out1;
      if ds_xfer = '1' and ds_write = '1' and be_i(3) = '1' then
        ld32_reg <= ld_i(31 downto 0);
      end if;
    end if;
  end process;


  mux_ram_banks : process (lclk0, rst_i)
  begin  -- process mux_ram_banks
    if rst_i = '1' then
      mem_out      <= (others => '0');
      ds_ready_mem <= '0';
    elsif lclk0'event and lclk0 = '1' then  -- rising clock edge
      case mem_reg(2 downto 0) is
        when "000" =>
          if (ready0 = '1' and ds_ready_mem = '0') or ds_xfer = '1' then
            mem_out    <= mem_out0;
          end if;        
          ds_ready_mem <= ready0;
        when "001" =>
          if (ready1 = '1' and ds_ready_mem = '0') or ds_xfer = '1' then
            mem_out      <= mem_out1;
          end if;   
          ds_ready_mem <= ready1;
        when "010" =>
          if (ready2 = '1' and ds_ready_mem = '0') or ds_xfer = '1' then
            mem_out      <= mem_out2;
          end if;   
          ds_ready_mem <= ready2;
        when "011" =>
          if (ready3 = '1' and ds_ready_mem = '0') or ds_xfer = '1' then
            mem_out      <= mem_out3;
          end if;   
          ds_ready_mem <= ready3;

        when others =>
          mem_out      <= (others => '0');
          ds_ready_mem <= '1';
      end case;
    end if;
  end process mux_ram_banks;


  --
  -- SRAM Interfaces
  --


  gen_qlads_mem : for i in 0 to 5 generate
    ds_xfer_mem(i) <= ds_xfer and la_q(21) and mem_reg_decode(i);
    qlads_mem(i)   <= qlads and la_i(21) and mem_reg_decode(i);
  end generate gen_qlads_mem;

  mem_addr     <= addr_reg(22 downto 19) & la_i(20 downto 3);
  mem_addr_ddr <= addr_reg(28 downto 19) & la_i(20 downto 3);

  mem_gnt <= ((mem_gnt_auto and mem_status) or mem_gnt_trig) and not EXT(mem_reg_decode,8);


  --
  -- DRAM Interface
  --

  gen_dram0 : if number_of_dram > 0 generate
    
    dramif0 : dram2if
--      generic map (
--       chipscope => true)
      port map (
        lclk              => lclk0,
        rst               => dcm_rst2_0,
        sysclk            => clk_i,
        dram_out          => dram0_out,
        dram_in           => dram0_in,
        ld_i              => ld_i,
        ld_o              => mem_out0,
        la_q              => mem_addr_ddr,
        lwrite            => lwrite,
        lblast            => blast_i,
        lbterm            => lbterm,
        ds_xfer           => ds_xfer_mem(0),
        lads              => qlads_mem(0),
        ready             => ready0,
        stop              => dram0_stop,
        lb_request        => mem_status(0),
        lb_grant          => mem_gnt(0),
        lb_rskip          => lb_rskip_reg,
        lb_roffset        => lb_roffset_reg,
        status          => mem_overflow0,
        debug => debug,
        clk_0             => clk_0,
        clk_90            => clk_90,
        CNTL_CLK_ID1         => ddr2_CLK_ID1,
        CNTL_CLK_ID2         => ddr2_CLK_ID2,
        CNTL_CLK_ID3         => ddr2_CLK_ID3,
        CNTL_CLK_ID4         => ddr2_CLK_ID4,
        sys_rst           => sys_rst0,
        sys_rst90         => sys_rst90_0,
        SYS_RST_ID        => SYS_RST_ID,
        idelay_ctrl_rdy   => idelay_ctrl_rdy,
        online            => mem_online(0),
        DDR2_RAS_N        => DDR0_RAS_N,
        DDR2_CAS_N        => DDR0_CAS_N,
        DDR2_WE_N         => DDR0_WE_N,
        DDR2_ODT          => DDR0_ODT,
        DDR2_CKE          => DDR0_CKE,
        DDR2_CS_N         => DDR0_CS_N,
        DDR2_DQ           => DDR0_DQ,
        DDR2_DQS          => DDR0_DQS,
        DDR2_DQS_N        => DDR0_DQS_N,
        DDR2_DM           => DDR0_DM,
        DDR2_CK           => DDR0_CK,
        DDR2_CK_N         => DDR0_CK_N,
        DDR2_BA           => DDR0_BA,
        DDR2_A            => DDR0_A);

  end generate gen_dram0;

  gen_not_dram0 : if number_of_dram < 1 generate
--    dram0_in      <= slv_to_extmem_type(CONV_STD_LOGIC_VECTOR(0, extmem_type_width));
    mem_out4      <= (others => '0');
    ready4        <= '1';
    dram1_stop    <= '0';
    mem_status(4) <= '0';
  end generate gen_not_dram0;


  gen_dram1 : if number_of_dram > 1 generate
    
    dramif1 : dram2if
--     generic map (
--        chipscope => true)
      port map (
        lclk              => lclk0,
        rst               => dcm_rst2_1,
        sysclk            => clk_i,
        dram_out          => dram1_out,
        dram_in           => dram1_in,
        ld_i              => ld_i,
        ld_o              => mem_out1,
        la_q              => mem_addr_ddr,
        lwrite            => lwrite,
        lblast            => blast_i,
        lbterm            => lbterm,
        ds_xfer           => ds_xfer_mem(1),
        lads              => qlads_mem(1),
        ready             => ready1,
        stop              => dram1_stop,
        lb_request        => mem_status(1),
        lb_grant          => mem_gnt(1),
        lb_rskip          => lb_rskip_reg,
        lb_roffset        => lb_roffset_reg,
        status          => mem_overflow1,
        debug => open,
        clk_0             => clk_0,
        clk_90            => clk_90,
        CNTL_CLK_ID1         => ddr2_CLK_ID1,
        CNTL_CLK_ID2         => ddr2_CLK_ID2,
        CNTL_CLK_ID3         => ddr2_CLK_ID3,
        CNTL_CLK_ID4         => ddr2_CLK_ID4,
        sys_rst           => sys_rst1,
        sys_rst90         => sys_rst90_1,
        SYS_RST_ID        => SYS_RST_ID,
        idelay_ctrl_rdy   => idelay_ctrl_rdy,
        online            => mem_online(1),
        DDR2_RAS_N        => DDR1_RAS_N,
        DDR2_CAS_N        => DDR1_CAS_N,
        DDR2_WE_N         => DDR1_WE_N,
        DDR2_ODT          => DDR1_ODT,
        DDR2_CKE          => DDR1_CKE,
        DDR2_CS_N         => DDR1_CS_N,
        DDR2_DQ           => DDR1_DQ,
        DDR2_DQS          => DDR1_DQS,
        DDR2_DQS_N        => DDR1_DQS_N,
        DDR2_DM           => DDR1_DM,
        DDR2_CK           => DDR1_CK,
        DDR2_CK_N         => DDR1_CK_N,
        DDR2_BA           => DDR1_BA,
        DDR2_A            => DDR1_A);

  end generate gen_dram1;

  gen_not_dram1 : if number_of_dram < 2 generate
--    dram1_in      <= slv_to_extmem_type(CONV_STD_LOGIC_VECTOR(0, extmem_type_width));
    mem_out1      <= (others => '0');
    ready1        <= '1';
    dram1_stop    <= '0';
    mem_status(1) <= '0';
  end generate gen_not_dram1;


  gen_dram2 : if number_of_dram > 2 generate
    
    dramif2 : dram2if
--     generic map (
--        chipscope => true)
      port map (
        lclk              => lclk0,
        rst               => dcm_rst2_2,
        sysclk            => clk_i,
        dram_out          => dram2_out,
        dram_in           => dram2_in,
        ld_i              => ld_i,
        ld_o              => mem_out2,
        la_q              => mem_addr_ddr,
        lwrite            => lwrite,
        lblast            => blast_i,
        lbterm            => lbterm,
        ds_xfer           => ds_xfer_mem(2),
        lads              => qlads_mem(2),
        ready             => ready2,
        stop              => dram2_stop,
        lb_request        => mem_status(2),
        lb_grant          => mem_gnt(2),
        lb_rskip          => lb_rskip_reg,
        lb_roffset        => lb_roffset_reg,
        status          => mem_overflow2,
        debug => open,
        clk_0             => clk_0,
        clk_90            => clk_90,
        CNTL_CLK_ID1         => ddr2_CLK_ID1,
        CNTL_CLK_ID2         => ddr2_CLK_ID2,
        CNTL_CLK_ID3         => ddr2_CLK_ID3,
        CNTL_CLK_ID4         => ddr2_CLK_ID4,
        sys_rst           => sys_rst2,
        sys_rst90         => sys_rst90_2,
        SYS_RST_ID        => SYS_RST_ID,
        idelay_ctrl_rdy   => idelay_ctrl_rdy,
        online            => mem_online(2),
        DDR2_RAS_N        => DDR2_RAS_N,
        DDR2_CAS_N        => DDR2_CAS_N,
        DDR2_WE_N         => DDR2_WE_N,
        DDR2_ODT          => DDR2_ODT,
        DDR2_CKE          => DDR2_CKE,
        DDR2_CS_N         => DDR2_CS_N,
        DDR2_DQ           => DDR2_DQ,
        DDR2_DQS          => DDR2_DQS,
        DDR2_DQS_N        => DDR2_DQS_N,
        DDR2_DM           => DDR2_DM,
        DDR2_CK           => DDR2_CK,
        DDR2_CK_N         => DDR2_CK_N,
        DDR2_BA           => DDR2_BA,
        DDR2_A            => DDR2_A);

  end generate gen_dram2;

  gen_not_dram2 : if number_of_dram < 3 generate
--    dram2_in      <= slv_to_extmem_type(CONV_STD_LOGIC_VECTOR(0, extmem_type_width));
    mem_out2      <= (others => '0');
    ready2        <= '1';
    dram2_stop    <= '0';
    mem_status(2) <= '0';
  end generate gen_not_dram2;


  gen_dram3 : if number_of_dram > 3 generate
    
    dramif3 : dram2if
 --    generic map (
 --       chipscope => true)
      port map (
        lclk              => lclk0,
        rst               => dcm_rst2_3,
        sysclk            => clk_i,
        dram_out          => dram3_out,
        dram_in           => dram3_in,
        ld_i              => ld_i,
        ld_o              => mem_out3,
        la_q              => mem_addr_ddr,
        lwrite            => lwrite,
        lblast            => blast_i,
        lbterm            => lbterm,
        ds_xfer           => ds_xfer_mem(3),
        lads              => qlads_mem(3),
        ready             => ready3,
        stop              => dram3_stop,
        lb_request        => mem_status(3),
        lb_grant          => mem_gnt(3),
        lb_rskip          => lb_rskip_reg,
        lb_roffset        => lb_roffset_reg,
        status          => mem_overflow3,
        debug => open,
        clk_0             => clk_0,
        clk_90            => clk_90,
        CNTL_CLK_ID1         => ddr2_CLK_ID1,
        CNTL_CLK_ID2         => ddr2_CLK_ID2,
        CNTL_CLK_ID3         => ddr2_CLK_ID3,
        CNTL_CLK_ID4         => ddr2_CLK_ID4,
        sys_rst           => sys_rst3,
        sys_rst90         => sys_rst90_3,
        SYS_RST_ID        => SYS_RST_ID,
        idelay_ctrl_rdy   => idelay_ctrl_rdy,
        online            => mem_online(3),
        DDR2_RAS_N        => DDR3_RAS_N,
        DDR2_CAS_N        => DDR3_CAS_N,
        DDR2_WE_N         => DDR3_WE_N,
        DDR2_ODT          => DDR3_ODT,
        DDR2_CKE          => DDR3_CKE,
        DDR2_CS_N         => DDR3_CS_N,
        DDR2_DQ           => DDR3_DQ,
        DDR2_DQS          => DDR3_DQS,
        DDR2_DQS_N        => DDR3_DQS_N,
        DDR2_DM           => DDR3_DM,
        DDR2_CK           => DDR3_CK,
        DDR2_CK_N         => DDR3_CK_N,
        DDR2_BA           => DDR3_BA,
        DDR2_A            => DDR3_A);

  end generate gen_dram3;

  gen_not_dram3 : if number_of_dram < 4 generate
    --   dram3_in      <= slv_to_extmem_type(CONV_STD_LOGIC_VECTOR(0, extmem_type_width));
    mem_out3      <= (others => '0');
    ready3        <= '1';
    dram3_stop    <= '0';
    mem_status(3) <= '0';
  end generate gen_not_dram3;

  --
    -- Instantiate the module that generates the SDRAM clocks
    --
    infrastructure:   mem_interface_infrastructure_DirectClk
    PORT MAP(
        SYS_CLK         => clk0,
        CLK200          => clk200_bufg_out,
        SYS_RESET_INn   => mem_rst,
        CLK             => clk_0,
        CLK90           => clk_90,
        CLK_ID1         => ddr2_CLK_ID1,
        CLK_ID2         => ddr2_CLK_ID2,
        CLK_ID3         => ddr2_CLK_ID3,
        CLK_ID4         => ddr2_CLK_ID4,
        idelay_ctrl_rdy => idelay_ctrl_rdy,
        LOCKED          => locked(3 downto 2),
        sys_rst         => sys_rst_i,
        sys_rst_90      => sys_rst90_i,
        SYS_RST_ID        => SYS_RST_ID);



      sys_rst90_0 <= sys_rst90_i;
      sys_rst90_1 <= sys_rst90_i;
      sys_rst90_2 <= sys_rst90_i;
      sys_rst90_3 <= sys_rst90_i;



   sys_rst_bufg : BUFG
    port map (
      I => sys_rst_i,
      O => sys_rst0);
 
      sys_rst1 <= sys_rst0;
      sys_rst2 <= sys_rst0;
      sys_rst3 <= sys_rst0;

  SYS_CLK <= adcclk;
  

  
    --
    -- Input the 200MHz Reference Clock
    --
  
    lvpecl_clk200_in : IBUFGDS_LVPECL_25
      port map (
          O	=> REF_CLK200_IN,
          I	=> clk200_p,
          IB => clk200_n
          );        
          
    clk_200bg : BUFG
        port map (
           O => clk200_bufg_out,
           I => REF_CLK200_IN
        );    
    
    


end mixed;

