-- ==============================================================
-- FILE : USER_AP3.VHD  -  MUST be modified by the USER
-- ==============================================================
--
-- This file is part of Example 3, for the HERON-FPGA14 module.
--
-- This file must be modified by the user.
--
-- ==============================================================
--
--  Date        : 06/04/2006
--  Author      : R. Williams - HUNT ENGINEERING
--  Description : User code section
--
-- ==============================================================
--
--  Ver     Modified By      Date      Changes
--  ---     -----------      ----      -------
--  1.0     R. Williams    06-04-06    Taken from FPGA12 Example 3.
--
-- ==============================================================



-- ==============================================================
--   Package : CONFIG
-- ==============================================================
--
-- This package allow users to set up the different clock domains
-- of the application (FIFO interfaces) in the top level.
-- Please refer to the HUNT documentation for more details.
--
-- ==============================================================

package CONFIG is

  -- FIFO CLOCK
  -- ==========

--   --------------------------------------------------------------------
--   Normally you will use the same clock source for the input and output
--   HERON FIFOs. In that case you need a single clock domain.
--   Then you drive SRC_FCLK_G with the frequency you want, which for the 
--   HEPC9/HECPCI9/HERON_BASE2 must be >=60Mhz and <= 100Mhz.
--   The clock you use in your design is then FCLK_G which has the corrct 
--   phase relative to the FIFO data.
--   In this case set FCLK_G_DOMAIN = TRUE

--   If however you want to use different clocks for the input and output 
--   HERON FIFOs, you have seperate clock domains.
--   Now you drive the signals SRC_FCLK_RD and SRC_FCLK_WR with the frequencies
--   you want, (still probably >60Mhz and <100Mhz) and your design must use 
--   FCLK_RD to deal with input FIFO data but FCLK_WR to deal with output FIFO data.  
--   In this case set FCLK_G_DOMAIN = FALSE

  -- To use a single common FIFO clock, set FCLK_G_DOMAIN = TRUE
  constant FCLK_G_DOMAIN : boolean := TRUE;

end CONFIG;


-- ==============================================================
--   Module : USER_AP
-- ==============================================================

library IEEE;
  use IEEE.std_logic_1164.all;
  use IEEE.std_logic_unsigned.all;
  use IEEE.numeric_std.all;
  use WORK.CONFIG.all;


--pragma translate_off
library sim_lib;
  use sim_lib.all;

library UNISIM;
  use UNISIM.VCOMPONENTS.all;
--pragma translate_on


entity USER_AP is
  port (
    RESET             : in  std_logic;                      -- Asynchronous reset active high
    CONFIG            : in  std_logic;                      -- System wide Config signal
-- CLOCK IO
    OSC0              : in  std_logic;                      -- Xtal OSC0
    OSC3              : in  std_logic;                      -- Xtal OSC3 factory default fitted with 100Mhz
-- MISCELLANEOUS IO
    UDPRES            : out std_logic;                      -- reset the carrier (high if NOT used)
    LED               : out std_logic_vector(4 downto 0);   -- LEDs
    MOD_HAS_PROC      : out std_logic;
    CID               : in  std_logic_vector(3 downto 0);   -- Carrier ID
    MID               : in  std_logic_vector(3 downto 0);   -- Module ID
-- UMIs
    UMI_IN            : in  std_logic_vector(3 downto 0);
    UMI_OUT           : out std_logic_vector(3 downto 0);
    UMI_EN            : out std_logic_vector(3 downto 0);
-- READ FIFO CLK
    FCLK_RD           : in  std_logic;                      -- FIFO_IN clock to be used in this module (only when FCLK_G_DOMAIN=FALSE)
    SRC_FCLK_RD       : out std_logic;                      -- FIFO_IN clock source for the top level  (only when FCLK_G_DOMAIN=FALSE)
-- WRITE FIFO CLK
    FCLK_WR           : in  std_logic;                      -- FIFO_OUT clock to be used in this module (only when FCLK_G_DOMAIN=FALSE)
    SRC_FCLK_WR       : out std_logic;                      -- FIFO_OUT clock source for the top level  (only when FCLK_G_DOMAIN=FALSE)
-- COMMON FIFO CLK
    FCLK_G            : in  std_logic;                      -- Common FIFO clock to be used in this module (only when FCLK_G_DOMAIN=TRUE)
    SRC_FCLK_G        : out std_logic;                      -- Common FIFO clock source for the top level  (only when FCLK_G_DOMAIN=TRUE)
-- FIFO IN / HE_RD_6F interface
    INFIFO_READ_REQ   : out std_logic_vector(5 downto 0);   -- FIFO_IN Read Request
    INFIFO_DVALID     : in  std_logic_vector(5 downto 0);   -- FIFO_IN Data Valid
    INFIFO_SINGLE     : in  std_logic_vector(5 downto 0);   -- FIFO_IN Single data item available
    INFIFO_BURST      : in  std_logic_vector(5 downto 0);   -- FIFO_IN Block of data available
    INFIFO0_D         : in  std_logic_vector(31 downto 0);  -- FIFO_IN Data for FIFO 0
    INFIFO1_D         : in  std_logic_vector(31 downto 0);  -- FIFO_IN Data for FIFO 1
    INFIFO2_D         : in  std_logic_vector(31 downto 0);  -- FIFO_IN Data for FIFO 2
    INFIFO3_D         : in  std_logic_vector(31 downto 0);  -- FIFO_IN Data for FIFO 3
    INFIFO4_D         : in  std_logic_vector(31 downto 0);  -- FIFO_IN Data for FIFO 4
    INFIFO5_D         : in  std_logic_vector(31 downto 0);  -- FIFO_IN Data for FIFO 5
-- FIFO OUT / HE_WR_6F interface
    OUTFIFO_READY     : in  std_logic_vector(5 downto 0);   -- FIFO_OUT Ready Flag
    OUTFIFO_WRITE     : out std_logic_vector(5 downto 0);   -- FIFO_OUT Write Command
    OUTFIFO_D         : out std_logic_vector(31 downto 0);  -- FIFO_OUT Data
-- SERIAL BUS / HE_USER Message interface
    MSG_CLK           : out std_logic;                      -- HSB clock source for the top level
    MSG_DIN           : in  std_logic_vector(7 downto 0);   -- data received from HSB
    MSG_ADDR          : in  std_logic_vector(7 downto 0);   -- HSB address
    MSG_AEN           : in  std_logic;                      -- address enable
    MSG_WEN           : in  std_logic;                      -- write access
    MSG_REN           : in  std_logic;                      -- read access
    MSG_DONE          : in  std_logic;                      -- message successfully transmitted
    MSG_COUNT         : in  std_logic;                      -- user's counter enable
    MSG_CLEAR         : in  std_logic;                      -- user's counter clear
    MSG_READY         : out std_logic;                      -- to acknowledge an access
    MSG_SEND_MSG      : out std_logic;                      -- message send command
    MSG_CE            : out std_logic;                      -- to control speed operation
    MSG_DOUT          : out std_logic_vector(7 downto 0);   -- data sent to HSB
    MSG_SEND_ID       : out std_logic;                      -- ID information send command
    MSG_LAST_BYTE     : out std_logic;                      -- to indicate when the last byte is presented
-- CONNECTOR DIGITAL IO
    CONN_A_IN         : in  std_logic_vector(29 downto 0);  -- Data input on Connector A
    CONN_A_OUT        : out std_logic_vector(29 downto 0);  -- Data output on Connector A
    CONN_A_EN         : out std_logic_vector(29 downto 0);  -- Output enables for Connector A
    CONN_B_IN         : in  std_logic_vector(29 downto 0);  -- Data input on Connector B
    CONN_B_OUT        : out std_logic_vector(29 downto 0);  -- Data output on Connector B
    CONN_B_EN         : out std_logic_vector(29 downto 0);  -- Output enables for Connector B
    CONN_C_IN         : in  std_logic_vector(29 downto 0);  -- Data input on Connector C
    CONN_C_OUT        : out std_logic_vector(29 downto 0);  -- Data output on Connector C
    CONN_C_EN         : out std_logic_vector(29 downto 0);  -- Output enables for Connector C
    CONN_D_IN         : in  std_logic_vector(29 downto 0);  -- Data input on Connector D
    CONN_D_OUT        : out std_logic_vector(29 downto 0);  -- Data output on Connector D
    CONN_D_EN         : out std_logic_vector(29 downto 0);  -- Output enables for Connector D
    CONN_E_IN         : in  std_logic_vector(29 downto 0);  -- Data input on Connector E
    CONN_E_OUT        : out std_logic_vector(29 downto 0);  -- Data output on Connector E
    CONN_E_EN         : out std_logic_vector(29 downto 0);  -- Output enables for Connector E
    CONN_F_IN         : in  std_logic_vector(29 downto 0);  -- Data input on Connector F
    CONN_F_OUT        : out std_logic_vector(29 downto 0);  -- Data output on Connector F
    CONN_F_EN         : out std_logic_vector(29 downto 0);  -- Output enables for Connector F
-- DDR User Clock A
    DDR_A_USER_CLK    : out std_logic;                      -- DDR Port A Clock source
-- DDR User Reset A
    DDR_A_USER_RST    : out std_logic;                      -- DDR Port A Data Count Reset
-- DDR Data Count
    DDR_A_DATA_COUNT  : in  std_logic_vector(31 downto 0);  -- DDR Port A Data Count
-- DDR Write Port A
    DDR_A_WR_DATA     : out std_logic_vector(71 downto 0);  -- DDR Port A Write Data
    DDR_A_WR_ADDR     : out std_logic_vector(24 downto 0);  -- DDR Port A Write Address
    DDR_A_WR_ADDR_WEN : out std_logic;                      -- DDR Port A Wr-Address Enable
    DDR_A_WR_ADDR_FF  : in  std_logic;                      -- DDR Port A Wr-Address Full Flag
    DDR_A_WR_ADDR_AF  : in  std_logic;                      -- DDR Port A Wr-Address Almost Full
    DDR_A_WR_RISE_WEN : out std_logic;                      -- DDR Port A Rising Data Enable
    DDR_A_WR_RISE_FF  : in  std_logic;                      -- DDR Port A Rising Data Full Flag
    DDR_A_WR_RISE_AF  : in  std_logic;                      -- DDR Port A Rising Data Almost Full
    DDR_A_WR_FALL_WEN : out std_logic;                      -- DDR Port A Falling Data Enable
    DDR_A_WR_FALL_FF  : in  std_logic;                      -- DDR Port A Falling Data Full Flag
    DDR_A_WR_FALL_AF  : in  std_logic;                      -- DDR Port A Falling Data Almost Full
    DDR_A_WR_DM_WEN   : out std_logic;                      -- DDR Port A Data Mask Enable
    DDR_A_WR_DM_FF    : in  std_logic;                      -- DDR Port A Data Mask Full Flag
    DDR_A_WR_DM_AF    : in  std_logic;                      -- DDR Port A Data Mask Almost Full
-- DDR Read Port A
    DDR_A_RD_DATA     : in  std_logic_vector(63 downto 0);  -- DDR Port A Read Data
    DDR_A_RD_ADDR     : out std_logic_vector(24 downto 0);  -- DDR Port A Read Address
    DDR_A_RD_ADDR_WEN : out std_logic;                      -- DDR Port A Rd-Address Enable
    DDR_A_RD_ADDR_FF  : in  std_logic;                      -- DDR Port A Rd-Address Full Flag
    DDR_A_RD_ADDR_AF  : in  std_logic;                      -- DDR Port A Rd-Address Almost Full
    DDR_A_RD_RISE_REN : out std_logic;                      -- DDR Port A Rising Data Enable
    DDR_A_RD_RISE_EF  : in  std_logic;                      -- DDR Port A Rising Data Empty Flag
    DDR_A_RD_RISE_AE  : in  std_logic;                      -- DDR Port A Rising Data Almost Empty
    DDR_A_RD_FALL_REN : out std_logic;                      -- DDR Port A Falling Data Enable
    DDR_A_RD_FALL_EF  : in  std_logic;                      -- DDR Port A Falling Data Empty Flag
    DDR_A_RD_FALL_AE  : in  std_logic                       -- DDR Port A Falling Data Almost Empty
  );
end USER_AP;


architecture EXAMPLE3 of USER_AP is

  component BUFG
    port ( I : in  std_logic;
           O : out std_logic);
  end component;

  component FIFO_CONTROL
    port (
      RESET      : in  std_logic;
      CLOCK      : in  std_logic;
      FIFO_WR    : in  std_logic;
      FIFO_RD    : in  std_logic;
      WRITE_FULL : out std_logic;
      READ_EMPTY : out std_logic
    );
  end component;

  component HSB3
    port (
      RST          : in  std_logic;
      CLK          : in  std_logic;
      DIN          : in  std_logic_vector(7 downto 0);
      ADDR         : in  std_logic_vector(7 downto 0);
      AEN          : in  std_logic;
      WEN          : in  std_logic;
      REN          : in  std_logic;
      DONE         : in  std_logic;
      COUNT        : in  std_logic;
      CLEAR        : in  std_logic;
      READY        : out std_logic;
      SEND_MSG     : out std_logic;
      CE           : out std_logic;
      DOUT         : out std_logic_vector(7 downto 0);
      SEND_ID      : out std_logic;
      LAST_BYTE    : out std_logic
    );
  end component;

  -- Asynchronous FIFO
  component fifo15x32
    port (
      din          : in  std_logic_vector(31 downto 0);
      wr_en        : in  std_logic;
      wr_clk       : in  std_logic;
      rd_en        : in  std_logic;
      rd_clk       : in  std_logic;
      ainit        : in  std_logic;
      dout         : out std_logic_vector(31 downto 0);
      full         : out std_logic;
      empty        : out std_logic;
      almost_full  : out std_logic;
      almost_empty : out std_logic
    );
  end component;

  -- Synchronous FIFO
  component FIFO16x32
    port (
      RESET    : in  std_logic;
      CLOCK    : in  std_logic;
      DIN      : in  std_logic_vector(31 downto 0);
      WR_EN    : in  std_logic;
      RD_EN    : in  std_logic;
      DOUT     : out std_logic_vector(31 downto 0);
      FULL     : out std_logic;
      EMPTY    : out std_logic;
      WR_COUNT : out std_logic_vector(4 downto 0);
      RD_COUNT : out std_logic_vector(4 downto 0)
    );
  end component;

  component DFS_DCM
    port (
      CLKIN_IN   : in  std_logic;
      RST_IN     : in  std_logic;
      CLKFX_OUT  : out std_logic;
      CLK0_OUT   : out std_logic;
      LOCKED_OUT : out std_logic
    );
  end component;

  signal MCLK                 : std_logic;

  signal HSB_CLK              : std_logic;
  signal HSB_CLOCK            : std_logic;

  signal SDCLK                : std_logic;

  signal IN_FIFO_A_DATA       : std_logic_vector(31 downto 0);
  signal IN_FIFO_A_RD         : std_logic;
  signal IN_FIFO_A_RD_DL      : std_logic;
  signal IN_FIFO_A_EF         : std_logic;
  signal IN_FIFO_A_AF         : std_logic;

  signal IN_FIFO_B_DATA       : std_logic_vector(31 downto 0);
  signal IN_FIFO_B_RD         : std_logic;
  signal IN_FIFO_B_RD_DL      : std_logic;
  signal IN_FIFO_B_EF         : std_logic;
  signal IN_FIFO_B_AF         : std_logic;

  signal WR_FIFO_A_RISE_DATA  : std_logic_vector(31 downto 0);
  signal WR_FIFO_A_FALL_DATA  : std_logic_vector(31 downto 0);
  signal WR_FIFO_A_RISE_WR_CT : std_logic_vector(4 downto 0);
  signal WR_FIFO_A_FALL_WR_CT : std_logic_vector(4 downto 0);
  signal WR_FIFO_A_RISE_WR    : std_logic;
  signal WR_FIFO_A_FALL_WR    : std_logic;
  signal WR_FIFO_A_WR_SEL     : std_logic;

  signal WR_FIFO_A_RD         : std_logic;
  signal WR_FIFO_A_RISE_EF    : std_logic;
  signal WR_FIFO_A_FALL_EF    : std_logic;
  signal WR_FIFO_A_RISE_AF    : std_logic;
  signal WR_FIFO_A_FALL_AF    : std_logic;
  signal WR_ADDRESS_A         : std_logic_vector(22 downto 0);
  signal WR_ADDR_WEN_A        : std_logic;
  signal WR_COUNT_A           : std_logic;
  signal WR_READY_A           : std_logic;

  signal WR_FIFO_B_RISE_DATA  : std_logic_vector(31 downto 0);
  signal WR_FIFO_B_FALL_DATA  : std_logic_vector(31 downto 0);
  signal WR_FIFO_B_RISE_WR_CT : std_logic_vector(4 downto 0);
  signal WR_FIFO_B_FALL_WR_CT : std_logic_vector(4 downto 0);
  signal WR_FIFO_B_RISE_WR    : std_logic;
  signal WR_FIFO_B_FALL_WR    : std_logic;
  signal WR_FIFO_B_WR_SEL     : std_logic;

  signal WR_FIFO_B_RD         : std_logic;
  signal WR_FIFO_B_RISE_EF    : std_logic;
  signal WR_FIFO_B_FALL_EF    : std_logic;
  signal WR_FIFO_B_RISE_AF    : std_logic;
  signal WR_FIFO_B_FALL_AF    : std_logic;
  signal WR_ADDRESS_B         : std_logic_vector(22 downto 0);
  signal WR_ADDR_WEN_B        : std_logic;
  signal WR_COUNT_B           : std_logic;
  signal WR_READY_B           : std_logic;

  signal FIFO_WR_A1           : std_logic;
  signal FIFO_WR_A2           : std_logic;
  signal FIFO_RD_A1           : std_logic;
  signal FIFO_RD_A2           : std_logic;

  signal FIFO_WR_B1           : std_logic;
  signal FIFO_WR_B2           : std_logic;
  signal FIFO_RD_B1           : std_logic;
  signal FIFO_RD_B2           : std_logic;

  signal WRITE_FULL_A         : std_logic;
  signal WRITE_FULL_A1        : std_logic;
  signal WRITE_FULL_A2        : std_logic;
  signal READ_EMPTY_A1        : std_logic;
  signal READ_EMPTY_A2        : std_logic;

  signal WRITE_FULL_B         : std_logic;
  signal WRITE_FULL_B1        : std_logic;
  signal WRITE_FULL_B2        : std_logic;
  signal READ_EMPTY_B1        : std_logic;
  signal READ_EMPTY_B2        : std_logic;

  signal BURST_COUNT_A        : std_logic_vector(2 downto 0);
  signal BURST_TC_A           : std_logic;

  signal BURST_COUNT_EN_A     : std_logic;
  signal BURST_SELECT_A       : std_logic;
  signal BURST_RESET_A        : std_logic;

  signal BURST_COUNT_B        : std_logic_vector(2 downto 0);
  signal BURST_TC_B           : std_logic;

  signal BURST_COUNT_EN_B     : std_logic;
  signal BURST_SELECT_B       : std_logic;
  signal BURST_RESET_B        : std_logic;

  signal RD_FIFO_A_RISE_OUT   : std_logic_vector(31 downto 0);
  signal RD_FIFO_A_FALL_OUT   : std_logic_vector(31 downto 0);
  signal RD_FIFO_A_RISE_WR_CT : std_logic_vector(4 downto 0);
  signal RD_FIFO_A_FALL_WR_CT : std_logic_vector(4 downto 0);
  signal RD_FIFO_A_RISE_WR    : std_logic;
  signal RD_FIFO_A_FALL_WR    : std_logic;
  signal RD_FIFO_A_RISE_RD    : std_logic;
  signal RD_FIFO_A_FALL_RD    : std_logic;
  signal RD_FIFO_A_RISE_EF    : std_logic;
  signal RD_FIFO_A_FALL_EF    : std_logic;
  signal RD_FIFO_A_RISE_AF    : std_logic;
  signal RD_FIFO_A_FALL_AF    : std_logic;

  signal RD_RISE_REN_A        : std_logic;
  signal RD_FALL_REN_A        : std_logic;
  signal RD_ADDR_WEN_A        : std_logic;

  signal RD_ADDRESS_A         : std_logic_vector(22 downto 0);
  signal RD_COUNT_A           : std_logic;
  signal RD_READY_A           : std_logic;
  signal RIP_A                : std_logic;

  signal RD_FIFO_OUT_A        : std_logic_vector(31 downto 0);
  signal RD_FIFO_WEN_A        : std_logic;
  signal RD_FIFO_SEL_A        : std_logic;

  signal RD_FIFO_B_RISE_OUT   : std_logic_vector(31 downto 0);
  signal RD_FIFO_B_FALL_OUT   : std_logic_vector(31 downto 0);
  signal RD_FIFO_B_RISE_WR_CT : std_logic_vector(4 downto 0);
  signal RD_FIFO_B_FALL_WR_CT : std_logic_vector(4 downto 0);
  signal RD_FIFO_B_RISE_WR    : std_logic;
  signal RD_FIFO_B_FALL_WR    : std_logic;
  signal RD_FIFO_B_RISE_RD    : std_logic;
  signal RD_FIFO_B_FALL_RD    : std_logic;
  signal RD_FIFO_B_RISE_EF    : std_logic;
  signal RD_FIFO_B_FALL_EF    : std_logic;
  signal RD_FIFO_B_RISE_AF    : std_logic;
  signal RD_FIFO_B_FALL_AF    : std_logic;

  signal RD_RISE_REN_B        : std_logic;
  signal RD_FALL_REN_B        : std_logic;
  signal RD_ADDR_WEN_B        : std_logic;

  signal RD_ADDRESS_B         : std_logic_vector(22 downto 0);
  signal RD_COUNT_B           : std_logic;
  signal RD_READY_B           : std_logic;
  signal RIP_B                : std_logic;

  signal RD_FIFO_OUT_B        : std_logic_vector(31 downto 0);
  signal RD_FIFO_WEN_B        : std_logic;
  signal RD_FIFO_SEL_B        : std_logic;

  signal OUT_FIFO_A_OUT       : std_logic_vector(31 downto 0);
  signal OUT_FIFO_A_RD        : std_logic;
  signal OUT_FIFO_A_EF        : std_logic;
  signal OUT_FIFO_A_AF        : std_logic;

  signal OUT_FIFO_B_OUT       : std_logic_vector(31 downto 0);
  signal OUT_FIFO_B_RD        : std_logic;
  signal OUT_FIFO_B_EF        : std_logic;
  signal OUT_FIFO_B_AF        : std_logic;

  signal OUT_FIFO_SEL         : std_logic;
  signal OUT_FIFO_SEL_DL      : std_logic;

  signal LED_COUNT_A          : std_logic_vector(23 downto 0);
  signal LED_COUNT_B          : std_logic_vector(23 downto 0);
  signal LED_COUNT_C          : std_logic_vector(23 downto 0);
  signal LED_COUNT_D          : std_logic_vector(23 downto 0);
  signal LED_COUNT_E          : std_logic_vector(24 downto 0);

  signal LED_COUNT_EN_A       : std_logic;
  signal LED_COUNT_EN_B       : std_logic;
  signal LED_COUNT_EN_C       : std_logic;
  signal LED_COUNT_EN_D       : std_logic;

  signal OSC3_CLK             : std_logic;

begin

  -- ==========================================================
  -- ==========================================================
  --       <<<<<<<   INSERT YOUR CODE HERE    >>>>>>>>>
  -- ==========================================================
  -- ==========================================================


  -------------------------------------------------------------
  -- Main clock to be used in this example

  iOSC3_BUFG : BUFG port map (I=>OSC3, O=>OSC3_CLK);

  MCLK <= OSC3_CLK;

  -------------------------------------------------------------
  -- Drive the UDP-RESET high (inactive)

  UDPRES <= '1';

  -------------------------------------------------------------
  -- Drive the MODULE HAS PROCESSOR signal high (inactive)

  MOD_HAS_PROC <= '1';

  -------------------------------------------------------------
  -- Drive unused signals

  UMI_OUT <= (others=>'0');
  UMI_EN  <= (others=>'1');

  -------------------------------------------------------------
  -- FIFO Clocks

  SRC_FCLK_RD <= '0';   -- clock source for READ FIFO
  SRC_FCLK_WR <= '0';   -- clock source for WRITE FIFO
  SRC_FCLK_G  <= MCLK;  -- global clock source for both FIFOs

  iDFS_DCM : DFS_DCM
    port map (
      CLKIN_IN   => OSC3_CLK,
      RST_IN     => RESET,
      LOCKED_OUT => open,
      CLKFX_OUT  => SDCLK,
      CLK0_OUT   => open );

  DDR_A_USER_CLK <= SDCLK;

  DDR_A_USER_RST <= RESET;

  INFIFO_READ_REQ(0) <= (NOT IN_FIFO_A_AF);
  INFIFO_READ_REQ(1) <= '0';
  INFIFO_READ_REQ(2) <= '0';
  INFIFO_READ_REQ(3) <= '0';
  INFIFO_READ_REQ(4) <= '0';
  INFIFO_READ_REQ(5) <= '0';

  -------------------------------------------------------------
  -- Input Data from HERON Input FIFOs

  iIN_FIFO_A : fifo15x32
    port map (
      din          => INFIFO0_D,
      wr_en        => INFIFO_DVALID(0),
      wr_clk       => FCLK_G,
      rd_en        => IN_FIFO_A_RD,
      rd_clk       => SDCLK,
      ainit        => RESET,
      dout         => IN_FIFO_A_DATA,
      full         => open,
      empty        => IN_FIFO_A_EF,
      almost_full  => IN_FIFO_A_AF,
      almost_empty => open );

  IN_FIFO_A_RD <= (NOT IN_FIFO_A_EF) AND WR_FIFO_A_RISE_AF AND WR_FIFO_A_FALL_AF;

  -------------------------------------------------------------
  -- DDR SDRAM Port A Write Interface

  WR_FIFO_A_RISE_AF <= '0' when WR_FIFO_A_RISE_WR_CT(4 downto 1)="0000" else '1';
  WR_FIFO_A_FALL_AF <= '0' when WR_FIFO_A_FALL_WR_CT(4 downto 1)="0000" else '1';

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      IN_FIFO_A_RD_DL <= '0';
    elsif rising_edge(SDCLK) then
      IN_FIFO_A_RD_DL <= IN_FIFO_A_RD;
    end if;
  end process;

  WR_FIFO_A_RISE_WR <= IN_FIFO_A_RD_DL AND (NOT WR_FIFO_A_WR_SEL);
  WR_FIFO_A_FALL_WR <= IN_FIFO_A_RD_DL AND      WR_FIFO_A_WR_SEL ;

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      WR_FIFO_A_WR_SEL <= '0';
    elsif rising_edge(SDCLK) then
      WR_FIFO_A_WR_SEL <= '0';
      if (WR_FIFO_A_WR_SEL='0' and WR_FIFO_A_RISE_WR='1') or
         (WR_FIFO_A_WR_SEL='1' and WR_FIFO_A_FALL_WR='0') then
        WR_FIFO_A_WR_SEL <= '1';
      end if;
    end if;
  end process;

  iWR_FIFO_RISE_A : FIFO16x32
    port map (
      RESET    => RESET,
      CLOCK    => SDCLK,
      DIN      => IN_FIFO_A_DATA,
      WR_EN    => WR_FIFO_A_RISE_WR,
      RD_EN    => WR_FIFO_A_RD,
      DOUT     => WR_FIFO_A_RISE_DATA,
      FULL     => open,
      EMPTY    => WR_FIFO_A_RISE_EF,
      WR_COUNT => WR_FIFO_A_RISE_WR_CT,
      RD_COUNT => open );

  iWR_FIFO_FALL_A : FIFO16x32
    port map (
      RESET    => RESET,
      CLOCK    => SDCLK,
      DIN      => IN_FIFO_A_DATA,
      WR_EN    => WR_FIFO_A_FALL_WR,
      RD_EN    => WR_FIFO_A_RD,
      DOUT     => WR_FIFO_A_FALL_DATA,
      FULL     => open,
      EMPTY    => WR_FIFO_A_FALL_EF,
      WR_COUNT => WR_FIFO_A_FALL_WR_CT,
      RD_COUNT => open );

  DDR_A_WR_RISE_WEN <= WR_FIFO_A_RD;
  DDR_A_WR_FALL_WEN <= WR_FIFO_A_RD;
  DDR_A_WR_DM_WEN   <= WR_FIFO_A_RD;

  WR_READY_A <= WR_FIFO_A_RISE_EF AND WR_FIFO_A_FALL_EF AND (NOT WRITE_FULL_A) AND
                (NOT DDR_A_WR_RISE_AF) AND (NOT DDR_A_WR_FALL_AF) AND (NOT DDR_A_WR_DM_AF);

  WR_FIFO_A_RD <= WR_READY_A AND (NOT BURST_SELECT_A);

  DDR_A_WR_DATA( 7 downto  0) <= (others=>'0');
  DDR_A_WR_DATA(39 downto  8) <= WR_FIFO_A_RISE_DATA;
  DDR_A_WR_DATA(71 downto 40) <= WR_FIFO_A_FALL_DATA;

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      WR_COUNT_A <= '0';
    elsif rising_edge(SDCLK) then
      if WR_FIFO_A_RD='1' then
        WR_COUNT_A <= '0';
        if WR_COUNT_A='0' then
          WR_COUNT_A <= '1';
        end if;
      end if;
    end if;
  end process;

  WR_ADDR_WEN_A <= WR_FIFO_A_RD AND WR_COUNT_A;

  DDR_A_WR_ADDR_WEN <= WR_ADDR_WEN_A;

  DDR_A_WR_ADDR <= WR_ADDRESS_A & "00";

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      WR_ADDRESS_A <= (others=>'0');
    elsif rising_edge(SDCLK) then
      if WR_ADDR_WEN_A='1' then
        WR_ADDRESS_A <= WR_ADDRESS_A + 1;
      end if;
    end if;
  end process;

  -------------------------------------------------------------
  -- DDR SDRAM Port A - logic to create a FIFO

  FIFO_WR_A1 <= WR_ADDR_WEN_A;
  FIFO_RD_A1 <= RD_ADDR_WEN_A;

  iFIFO_CTRL_A1 : FIFO_CONTROL
    port map (
      RESET      => RESET,
      CLOCK      => SDCLK,
      FIFO_WR    => FIFO_WR_A1,
      FIFO_RD    => FIFO_RD_A1,
      WRITE_FULL => WRITE_FULL_A1,
      READ_EMPTY => READ_EMPTY_A1 );

  FIFO_WR_A2 <= WR_ADDR_WEN_A;
  FIFO_RD_A2 <= RD_FIFO_A_FALL_WR AND RD_COUNT_A;

  iFIFO_CTRL_A2 : FIFO_CONTROL
    port map (
      RESET      => RESET,
      CLOCK      => SDCLK,
      FIFO_WR    => FIFO_WR_A2,
      FIFO_RD    => FIFO_RD_A2,
      WRITE_FULL => WRITE_FULL_A2,
      READ_EMPTY => open );

  WRITE_FULL_A <= WRITE_FULL_A1 OR WRITE_FULL_A2;

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      READ_EMPTY_A2 <= '1';
    elsif rising_edge(SDCLK) then
      READ_EMPTY_A2 <= '0';
      if DDR_A_DATA_COUNT="00000000000000000000000000000000" then
        READ_EMPTY_A2 <= '1';
      end if;
    end if;
  end process;

  -------------------------------------------------------------
  -- DDR Burst Control A

  BURST_COUNT_EN_A <= WR_ADDR_WEN_A OR RD_ADDR_WEN_A;

  BURST_RESET_A <= ((NOT BURST_SELECT_A) AND (NOT WR_READY_A) AND      RD_READY_A ) OR
                   (     BURST_SELECT_A  AND      WR_READY_A  AND (NOT RD_READY_A));

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      BURST_COUNT_A <= (others=>'0');
    elsif rising_edge(SDCLK) then
      if BURST_RESET_A='1' then
        BURST_COUNT_A <= (others=>'0');
      elsif BURST_COUNT_EN_A='1' then
        BURST_COUNT_A <= BURST_COUNT_A + 1;
      end if;
    end if;
  end process;

  BURST_TC_A <= '1' when BURST_COUNT_A="111" else '0';

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      BURST_SELECT_A <= '0';
    elsif rising_edge(SDCLK) then
      if (BURST_COUNT_EN_A='1' and BURST_TC_A='1') or (BURST_RESET_A='1') then
        BURST_SELECT_A <= '0';
        if BURST_SELECT_A='0' then
          BURST_SELECT_A <= '1';
        end if;
      end if;
    end if;
  end process;

  -------------------------------------------------------------
  -- DDR SDRAM Port A Read Interface

  DDR_A_RD_RISE_REN <= RD_RISE_REN_A;
  DDR_A_RD_FALL_REN <= RD_FALL_REN_A;

  RD_RISE_REN_A <= (NOT DDR_A_RD_RISE_EF) AND RD_FIFO_A_RISE_AF;
  RD_FALL_REN_A <= (NOT DDR_A_RD_FALL_EF) AND RD_FIFO_A_FALL_AF;

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      RD_FIFO_A_RISE_WR <= '0';
      RD_FIFO_A_FALL_WR <= '0';
    elsif rising_edge(SDCLK) then
      RD_FIFO_A_RISE_WR <= '0';
      RD_FIFO_A_FALL_WR <= '0';
      if RD_RISE_REN_A='1' then
        RD_FIFO_A_RISE_WR <= '1';
      end if;
      if RD_FALL_REN_A='1' then
        RD_FIFO_A_FALL_WR <= '1';
      end if;
    end if;
  end process;

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      RD_COUNT_A <= '0';
    elsif rising_edge(SDCLK) then
      if RD_FIFO_A_FALL_WR='1' then
        RD_COUNT_A <= '0';
        if RD_COUNT_A='0' then
          RD_COUNT_A <= '1';
        end if;
      end if;
    end if;
  end process;

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      RIP_A <= '0';
    elsif rising_edge(SDCLK) then
      RIP_A <= '0';
      if RD_ADDR_WEN_A='1' then
        RIP_A <= '1';
      end if;
    end if;
  end process;

  RD_READY_A <= (NOT DDR_A_RD_ADDR_AF) AND (NOT READ_EMPTY_A1) AND (NOT READ_EMPTY_A2);

  RD_ADDR_WEN_A <= (NOT RIP_A) AND RD_READY_A AND BURST_SELECT_A;

  DDR_A_RD_ADDR_WEN <= RD_ADDR_WEN_A;

  DDR_A_RD_ADDR <= RD_ADDRESS_A & "00";

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      RD_ADDRESS_A <= (others=>'0');
    elsif rising_edge(SDCLK) then
      if RD_ADDR_WEN_A='1' then
        RD_ADDRESS_A <= RD_ADDRESS_A + 1;
      end if;
    end if;
  end process;

  iRD_FIFO_RISE_A : FIFO16x32
    port map (
      RESET    => RESET,
      CLOCK    => SDCLK,
      DIN      => DDR_A_RD_DATA(31 downto 0),
      WR_EN    => RD_FIFO_A_RISE_WR,
      RD_EN    => RD_FIFO_A_RISE_RD,
      DOUT     => RD_FIFO_A_RISE_OUT,
      FULL     => open,
      EMPTY    => RD_FIFO_A_RISE_EF,
      WR_COUNT => RD_FIFO_A_RISE_WR_CT,
      RD_COUNT => open );

  iRD_FIFO_FALL_A : FIFO16x32
    port map (
      RESET    => RESET,
      CLOCK    => SDCLK,
      DIN      => DDR_A_RD_DATA(63 downto 32),
      WR_EN    => RD_FIFO_A_FALL_WR,
      RD_EN    => RD_FIFO_A_FALL_RD,
      DOUT     => RD_FIFO_A_FALL_OUT,
      FULL     => open,
      EMPTY    => RD_FIFO_A_FALL_EF,
      WR_COUNT => RD_FIFO_A_FALL_WR_CT,
      RD_COUNT => open );

  -- Indicate almost full when 1 word to write or less
  RD_FIFO_A_RISE_AF <= '0' when RD_FIFO_A_RISE_WR_CT(4 downto 1)="0000" else '1';
  RD_FIFO_A_FALL_AF <= '0' when RD_FIFO_A_FALL_WR_CT(4 downto 1)="0000" else '1';

  -------------------------------------------------------------
  -- Transfer SDRAM Data to HERON Output FIFOs

  RD_FIFO_A_RISE_RD <= (NOT OUT_FIFO_A_AF) AND RD_FIFO_A_RISE_EF AND (NOT RD_FIFO_SEL_A);
  RD_FIFO_A_FALL_RD <= (NOT OUT_FIFO_A_AF) AND RD_FIFO_A_FALL_EF AND      RD_FIFO_SEL_A ;

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      RD_FIFO_SEL_A <= '0';
    elsif rising_edge(SDCLK) then
      RD_FIFO_SEL_A <= '0';
      if (RD_FIFO_SEL_A='0' and RD_FIFO_A_RISE_RD='1') or
         (RD_FIFO_SEL_A='1' and RD_FIFO_A_FALL_RD='0') then
        RD_FIFO_SEL_A <= '1';
      end if;
    end if;
  end process;

  RD_FIFO_OUT_A <= RD_FIFO_A_RISE_OUT when RD_FIFO_SEL_A='0' else RD_FIFO_A_FALL_OUT;

  RD_FIFO_WEN_A <= RD_FIFO_A_RISE_RD  when RD_FIFO_SEL_A='0' else RD_FIFO_A_FALL_RD;

  iOUT_FIFO_A : fifo15x32
    port map (
      din          => RD_FIFO_OUT_A,
      wr_en        => RD_FIFO_WEN_A,
      wr_clk       => SDCLK,
      rd_en        => OUT_FIFO_A_RD,
      rd_clk       => FCLK_G,
      ainit        => RESET,
      dout         => OUT_FIFO_A_OUT,
      full         => open,
      empty        => OUT_FIFO_A_EF,
      almost_full  => OUT_FIFO_A_AF,
      almost_empty => open );

  OUTFIFO_D <= OUT_FIFO_A_OUT;

  OUT_FIFO_A_RD <= OUTFIFO_READY(0) AND (NOT OUT_FIFO_A_EF);

  process(RESET, FCLK_G)
  begin
    if RESET='1' then
      OUTFIFO_WRITE(0) <= '0';
    elsif rising_edge(FCLK_G) then
      OUTFIFO_WRITE(0) <= OUT_FIFO_A_RD;
    end if;
  end process;

  OUTFIFO_WRITE(1) <= '0';
  OUTFIFO_WRITE(2) <= '0';
  OUTFIFO_WRITE(3) <= '0';
  OUTFIFO_WRITE(4) <= '0';
  OUTFIFO_WRITE(5) <= '0';

  -------------------------------------------------------------
  -- Serial Bus

  iHSB_BUFG : BUFG port map (I=>HSB_CLK, O=>HSB_CLOCK);

  process (OSC3_CLK)
  begin
    if rising_edge(OSC3_CLK) then
      HSB_CLK <= NOT HSB_CLK;
    end if;
  end process;

  MSG_CLK <= HSB_CLOCK;  -- clock for Message Interface

  iHSB3 : HSB3
    port map (
      RST       => RESET,
      CLK       => HSB_CLOCK,
      DIN       => MSG_DIN,
      ADDR      => MSG_ADDR,
      AEN       => MSG_AEN,
      WEN       => MSG_WEN,
      REN       => MSG_REN,
      DONE      => MSG_DONE,
      COUNT     => MSG_COUNT,
      CLEAR     => MSG_CLEAR,
      READY     => MSG_READY,
      SEND_MSG  => MSG_SEND_MSG,
      CE        => MSG_CE,
      DOUT      => MSG_DOUT,
      SEND_ID   => MSG_SEND_ID,
      LAST_BYTE => MSG_LAST_BYTE );

  -------------------------------------------------------------
  -- Connector Digital IO (not used in this example)

  CONN_A_OUT <= (others=>'0');
  CONN_A_EN  <= (others=>'1');

  CONN_B_OUT <= (others=>'0');
  CONN_B_EN  <= (others=>'1');

  CONN_C_OUT <= (others=>'0');
  CONN_C_EN  <= (others=>'1');

  CONN_D_OUT <= (others=>'0');
  CONN_D_EN  <= (others=>'1');

  CONN_E_OUT <= (others=>'0');
  CONN_E_EN  <= (others=>'1');

  CONN_F_OUT <= (others=>'0');
  CONN_F_EN  <= (others=>'1');

  -------------------------------------------------------------
  -- Leds indicating FULL and EMPTY conditions on DDR SDRAM FIFOs A & B

  process(RESET, FCLK_G)
  begin
    if RESET='1' then
      LED_COUNT_EN_A <= '0';
    elsif rising_edge(FCLK_G) then
      LED_COUNT_EN_A <= '0';
      if READ_EMPTY_A1='1' or READ_EMPTY_A2='1' then
        LED_COUNT_EN_A <= '1';
      end if;
    end if;
  end process;

  process(RESET, FCLK_G)
  begin
    if RESET='1' then
      LED_COUNT_EN_B <= '0';
    elsif rising_edge(FCLK_G) then
      LED_COUNT_EN_B <= '0';
      if WRITE_FULL_A='1' then
        LED_COUNT_EN_B <= '1';
      end if;
    end if;
  end process;

  process(RESET, FCLK_G)
  begin
    if RESET='1' then
      LED_COUNT_A <= (others=>'0');
    elsif rising_edge(FCLK_G) then
      if LED_COUNT_EN_A='1' then
        LED_COUNT_A <= (others=>'0');
      else
        if LED_COUNT_A(23)='0' then
          LED_COUNT_A <= LED_COUNT_A + 1;
        end if;
      end if;
    end if;
  end process;

  process(RESET, FCLK_G)
  begin
    if RESET='1' then
      LED_COUNT_B <= (others=>'0');
    elsif rising_edge(FCLK_G) then
      if LED_COUNT_EN_B='1' then
        LED_COUNT_B <= (others=>'0');
      else
        if LED_COUNT_B(23)='0' then
          LED_COUNT_B <= LED_COUNT_B + 1;
        end if;
      end if;
    end if;
  end process;

  LED(0) <= LED_COUNT_A(23);
  LED(1) <= LED_COUNT_B(23);
  LED(2) <= '1';
  LED(3) <= '1';

  -------------------------------------------------------------
  -- Led Flasher : dividing F_CLKG clock by 2**24

  process(RESET, FCLK_G)
  begin
    if RESET='1' then
      LED_COUNT_E <= (others=>'0');
    elsif rising_edge(FCLK_G) then
      LED_COUNT_E <= LED_COUNT_E + 1;
    end if;
  end process;

  LED(4) <= LED_COUNT_E(24);

end EXAMPLE3;
