-- ==============================================================
-- FILE : CAM_DEMO.VHD  -  May be modified by the USER
-- ==============================================================
--
-- This file is part of the Image Processing Demo.
--
-- This file can be modified by the users to implement their own
-- logic.
--
-- ==============================================================
--
--  Date        : 12/06/2006
--  Author      : R. Williams
--  Description : Camera Imaging Demo
--
-- ==============================================================
--
--  Ver     Modified By      Date      Changes
--  ---     -----------      ----      -------
--  1.0     R. Williams    12-06-06    First Written
--  3.1     R. Williams    07-09-07    Changes to CamLink_IF.vhd
--                                     to ensure correct operation
--                                     under ISE9.1.
--
-- ==============================================================



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


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


entity CAM_DEMO is
  generic (
    Use_Low_Freq_Deserialiser : boolean := TRUE;
    Use_5x5_Convolution       : boolean := TRUE
  );
  port (
    -- Clock and Reset
    RESET          : in  std_logic;
    HSB_CLOCK      : in  std_logic;
    -- CameraLink interface
    CAM_CLK        : in  std_logic;
    CAM_DATA       : in  std_logic_vector(3 downto 0);
    CAM_CTRL       : out std_logic_vector(3 downto 0);
    CAM_SER_TC     : out std_logic;
    CAM_SER_TFG    : in  std_logic;
    -- HERON Output FIFO interface
    FCLK_G         : in  std_logic;
    OUTFIFO_READY  : in  std_logic_vector(5 downto 0);
    OUTFIFO_WRITE  : out std_logic_vector(5 downto 0);
    OUTFIFO_D      : out std_logic_vector(31 downto 0);
    -- User Message interface
    MSG_DIN        : in  std_logic_vector(7 downto 0);
    MSG_ADDR       : in  std_logic_vector(7 downto 0);
    MSG_AEN        : in  std_logic;
    MSG_WEN        : in  std_logic;
    MSG_REN        : in  std_logic;
    MSG_DONE       : in  std_logic;
    MSG_COUNT      : in  std_logic;
    MSG_CLEAR      : in  std_logic;
    MSG_READY      : out std_logic;
    MSG_SEND_MSG   : out std_logic;
    MSG_CE         : out std_logic;
    MSG_DOUT       : out std_logic_vector(7 downto 0);
    MSG_SEND_ID    : out std_logic;
    MSG_LAST_BYTE  : out std_logic;
    -- DDR interface
    DDR_A_USER_CLK    : out std_logic;
    DDR_A_USER_RST    : out std_logic;
    DDR_A_DATA_COUNT  : in  std_logic_vector(31 downto 0);
    DDR_A_WR_DATA     : out std_logic_vector(71 downto 0);
    DDR_A_WR_ADDR     : out std_logic_vector(24 downto 0);
    DDR_A_WR_ADDR_WEN : out std_logic;
    DDR_A_WR_ADDR_FF  : in  std_logic;
    DDR_A_WR_ADDR_AF  : in  std_logic;
    DDR_A_WR_RISE_WEN : out std_logic;
    DDR_A_WR_RISE_FF  : in  std_logic;
    DDR_A_WR_RISE_AF  : in  std_logic;
    DDR_A_WR_FALL_WEN : out std_logic;
    DDR_A_WR_FALL_FF  : in  std_logic;
    DDR_A_WR_FALL_AF  : in  std_logic;
    DDR_A_WR_DM_WEN   : out std_logic;
    DDR_A_WR_DM_FF    : in  std_logic;
    DDR_A_WR_DM_AF    : in  std_logic;
    DDR_A_RD_DATA     : in  std_logic_vector(63 downto 0);
    DDR_A_RD_ADDR     : out std_logic_vector(24 downto 0);
    DDR_A_RD_ADDR_WEN : out std_logic;
    DDR_A_RD_ADDR_FF  : in  std_logic;
    DDR_A_RD_ADDR_AF  : in  std_logic;
    DDR_A_RD_RISE_REN : out std_logic;
    DDR_A_RD_RISE_EF  : in  std_logic;
    DDR_A_RD_RISE_AE  : in  std_logic;
    DDR_A_RD_FALL_REN : out std_logic;
    DDR_A_RD_FALL_EF  : in  std_logic;
    DDR_A_RD_FALL_AE  : in  std_logic
  );
end CAM_DEMO;


architecture RTL of CAM_DEMO is

  component CLINK is
    generic (
      LFreq_Deserialiser : boolean := TRUE
    );
    port (
      RESET       : in  std_logic;
      CAM_CLK     : in  std_logic;
      CAM_DATA    : in  std_logic_vector(3 downto 0);
      POLARITY    : in  std_logic;
      USE_DVAL    : in  std_logic;
      BIT_SEL     : in  std_logic_vector(1 downto 0);
      PIXEL_CLOCK : out std_logic;
      DVALID_OUT  : out std_logic;
      EOL_OUT     : out std_logic;
      EOF_OUT     : out std_logic;
      DATA_OUT    : out std_logic_vector(31 downto 0);
      ACTIVE      : out std_logic_vector(3 downto 0)
    );
  end component;

  component AUTO_ROI is
    port (
      RESET       : in  std_logic;
      PIXEL_CLOCK : in  std_logic;
      DVALID_IN   : in  std_logic;
      EOL_IN      : in  std_logic;
      EOF_IN      : in  std_logic;
      DATA_IN     : in  std_logic_vector(31 downto 0);
      FIRST_PIXEL : out std_logic_vector(11 downto 0);
      LAST_PIXEL  : out std_logic_vector(11 downto 0);
      FIRST_LINE  : out std_logic_vector(11 downto 0);
      LAST_LINE   : out std_logic_vector(11 downto 0);
      PIXEL_TOTAL : out std_logic_vector(11 downto 0);
      LINE_TOTAL  : out std_logic_vector(11 downto 0);
      ROI_VALID   : out std_logic
    );
  end component;

  component ROI is
    port (
      RESET       : in  std_logic;
      PIXEL_CLOCK : in  std_logic;
      ODD_ONLY    : in  std_logic;
      DVALID_IN   : in  std_logic;
      EOL_IN      : in  std_logic;
      EOF_IN      : in  std_logic;
      DVALID_OUT  : out std_logic;
      EOL_OUT     : out std_logic;
      EOF_OUT     : out std_logic;
      START_PIXEL : in  std_logic_vector(11 downto 0);
      STOP_PIXEL  : in  std_logic_vector(11 downto 0);
      START_LINE  : in  std_logic_vector(11 downto 0);
      STOP_LINE   : in  std_logic_vector(11 downto 0);
      DATA_IN     : in  std_logic_vector(31 downto 0);
      DATA_OUT    : out std_logic_vector(31 downto 0)
    );
  end component;

  component FRAME_CONTROL is
    port (
      RESET       : in  std_logic;
      PIXEL_CLOCK : in  std_logic;
      CONTINUOUS  : in  std_logic;
      DVALID_IN   : in  std_logic;
      EOL_IN      : in  std_logic;
      EOF_IN      : in  std_logic;
      DVALID_OUT  : out std_logic;
      EOL_OUT     : out std_logic;
      EOF_OUT     : out std_logic;
      LOAD        : in  std_logic;
      FRAMES      : in  std_logic_vector(3 downto 0);
      DATA_IN     : in  std_logic_vector(31 downto 0);
      DATA_OUT    : out std_logic_vector(31 downto 0)
    );
  end component;

  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;

  component FIFO16x32 is
    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 invert is
    generic (
      Synchronous : boolean := True;
      N           : integer := 32
    );
    port (
      DATA_IN    : in  std_logic_vector(N-1 downto 0);
      DATA_OUT   : out std_logic_vector(N-1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic
    );
  end component;

  component ADDK is
    generic (
      Synchronous : boolean := True;
      N           : integer := 32
    );
    port (
      DATA_IN    : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      K_IN       : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component ORK is
    generic (
      Synchronous : boolean := True;
      N           : integer := 32
    );
    port (
      DATA_IN    : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      K_IN       : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component SUBK is
    generic (
      Synchronous : boolean := True;
      StopAtZero  : boolean := True;
      N           : integer := 32
    );
    port (
      DATA_IN    : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      K_IN       : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component XORK is
    generic (
      Synchronous : boolean := True;
      N           : integer := 32
    );
    port (
      DATA_IN    : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      K_IN       : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component SQUARE is
    generic (
      Synchronous : boolean := True;
      N           : integer := 18
    );
    port (
      DATA_IN    : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic
    );
  end component;

  component MPYK is
    generic (
      Synchronous : boolean := True;
      N           : integer := 18
    );
    port (
      DATA_IN    : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      K_IN       : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component LSHK is
    generic (
      Synchronous : boolean := True;
      FillWithOnes: boolean := False;
      N           : integer := 32
    );
    port (
      DATA_IN    : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      K_IN       : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component RSHK is
    generic (
      Synchronous  : boolean := True;
      FillWithOnes : boolean := False;
      N            : integer := 32
    );
    port (
      DATA_IN    : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      K_IN       : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component ANDK is
    generic (
      Synchronous : boolean := True;
      N           : integer := 32
    );
    port (
      DATA_IN    : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      K_IN       : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component FILLRAMP  is
    generic (
      N          : integer := 32
    );
    port (
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      K_IN       : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component XORImage is
    generic (
      N          : integer := 32
    );
    port (
      DATA_A     : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_A   : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      REQ_PIXEL  : out std_logic;
      DATA_B     : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component FILLK is
    generic (
      N          : integer := 32
    );
    port (
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      K_IN       : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component SUBImage is
    generic (
      StopAtZero : boolean := True;
      N          : integer := 32
    );
    port (
      DATA_A     : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_A   : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      REQ_PIXEL  : out std_logic;
      DATA_B     : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component ADDImage is
    generic (
      N          : integer := 32
    );
    port (
      DATA_A     : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_A   : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      REQ_PIXEL  : out std_logic;
      DATA_B     : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component ANDIMAGE is
    generic (
      N          : integer := 32
    );
    port (
      DATA_A     : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_A   : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      REQ_PIXEL  : out std_logic;
      DATA_B     : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component ORImage is
    generic (
      N          : integer := 32
    );
    port (
      DATA_A     : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_A   : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      REQ_PIXEL  : out std_logic;
      DATA_B     : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  component MPYImage is
    generic (
      N          : integer := 18
    );
    port (
      DATA_A     : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_A   : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      REQ_PIXEL  : out std_logic;
      DATA_B     : in  std_logic_vector(N - 1 downto 0)
    );
  end component;

  --3x3 convolution function
  component convolve is
    generic (
      N              : integer := 32;
      LINE_LENGTH    : integer := 32;
      RAM_ADDR_WIDTH : integer := 5;
      KERNEL         : string  := "GENERAL"
    );
    port (
      DATA_IN    : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      K_A1       : in  std_logic_vector(17 downto 0);
      K_A2       : in  std_logic_vector(17 downto 0);
      K_A3       : in  std_logic_vector(17 downto 0);
      K_B1       : in  std_logic_vector(17 downto 0);
      K_B2       : in  std_logic_vector(17 downto 0);
      K_B3       : in  std_logic_vector(17 downto 0);
      K_C1       : in  std_logic_vector(17 downto 0);
      K_C2       : in  std_logic_vector(17 downto 0);
      K_C3       : in  std_logic_vector(17 downto 0);
      SHIFT      : in  std_logic_vector(3 downto 0);
      CLOCK      : in  std_logic;
      RESET      : in  std_logic
    );
  end component;

  --5x5 convolution function
  component convolve5x5 is
    generic(
      N              : integer := 8;
      LINE_LENGTH    : integer := 32;
      RAM_ADDR_WIDTH : integer := 5;
      KERNEL         : string  := "GENERAL"
    );
    port (
      DATA_IN    : in  std_logic_vector(N - 1 downto 0);
      DATA_OUT   : out std_logic_vector(N - 1 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic;
      K_A1       : in  std_logic_vector(17 downto 0);
      K_A2       : in  std_logic_vector(17 downto 0);
      K_A3       : in  std_logic_vector(17 downto 0);
      K_A4       : in  std_logic_vector(17 downto 0);
      K_A5       : in  std_logic_vector(17 downto 0);
      K_B1       : in  std_logic_vector(17 downto 0);
      K_B2       : in  std_logic_vector(17 downto 0);
      K_B3       : in  std_logic_vector(17 downto 0);
      K_B4       : in  std_logic_vector(17 downto 0);
      K_B5       : in  std_logic_vector(17 downto 0);
      K_C1       : in  std_logic_vector(17 downto 0);
      K_C2       : in  std_logic_vector(17 downto 0);
      K_C3       : in  std_logic_vector(17 downto 0);
      K_C4       : in  std_logic_vector(17 downto 0);
      K_C5       : in  std_logic_vector(17 downto 0);
      K_D1       : in  std_logic_vector(17 downto 0);
      K_D2       : in  std_logic_vector(17 downto 0);
      K_D3       : in  std_logic_vector(17 downto 0);
      K_D4       : in  std_logic_vector(17 downto 0);
      K_D5       : in  std_logic_vector(17 downto 0);
      K_E1       : in  std_logic_vector(17 downto 0);
      K_E2       : in  std_logic_vector(17 downto 0);
      K_E3       : in  std_logic_vector(17 downto 0);
      K_E4       : in  std_logic_vector(17 downto 0);
      K_E5       : in  std_logic_vector(17 downto 0);
      SHIFT      : in  std_logic_vector(3 downto 0);
      CLOCK      : in  std_logic;
      RESET      : in  std_logic
    );
  end component;

  component PACK_SYNC
    port (
      RESET       : in  std_logic;
      PIXEL_CLOCK : in  std_logic;
      M4_X_8      : in  std_logic;
      M2_X_16     : in  std_logic;
      M1_X_32     : in  std_logic;
      DVALID_IN   : in  std_logic;
      EOL_IN      : in  std_logic;
      EOF_IN      : in  std_logic;
      DVALID_OUT  : out std_logic;
      DATA_IN     : in  std_logic_vector(31 downto 0);
      DATA_OUT    : out std_logic_vector(31 downto 0)
    );
  end component;

  --Output FIFO
  component fifo511x32
    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;
      wr_count     : out std_logic_vector(4 downto 0);
      rd_count     : out std_logic_vector(4 downto 0)
    );
  end component;

  component fifo2047x32
    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;

  component CAMLINK_HSB is
    port (
      RESET           : in  std_logic;
      CLOCK           : in  std_logic;
      PIXEL_CLOCK     : 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;
      M4_X_8          : out std_logic;
      M2_X_16         : out std_logic;
      M1_X_32         : out std_logic;
      BIT_SEL         : out std_logic_vector(1 downto 0);
      CP_SEL          : out std_logic;
      CONTINUOUS      : out std_logic;
      ODD_ONLY        : out std_logic;
      LOAD            : out std_logic;
      FRAMES          : out std_logic_vector(3 downto 0);
      AUTO_RES        : out std_logic;
      POLARITY        : out std_logic;
      USE_DVAL        : out std_logic;
      CAM_INPUTS      : out std_logic_vector(3 downto 0);
      START_PIXEL     : out std_logic_vector(11 downto 0);
      STOP_PIXEL      : out std_logic_vector(11 downto 0);
      START_LINE      : out std_logic_vector(11 downto 0);
      STOP_LINE       : out std_logic_vector(11 downto 0);
      OUTFIFO_SEL     : out std_logic_vector(5 downto 0);
      TX              : out std_logic;
      RX              : in  std_logic;
      PIXEL_TOTAL     : in  std_logic_vector(11 downto 0);
      LINE_TOTAL      : in  std_logic_vector(11 downto 0);
      FIRST_PIXEL     : in  std_logic_vector(11 downto 0);
      LAST_PIXEL      : in  std_logic_vector(11 downto 0);
      FIRST_LINE      : in  std_logic_vector(11 downto 0);
      LAST_LINE       : in  std_logic_vector(11 downto 0);
      ACTIVE          : in  std_logic_vector(3 downto 0);
      ROI_VALID       : in  std_logic;
      IMAGE_BLOCK_SEL : out std_logic_vector(7 downto 0);
      CAT1_CONST      : out std_logic_vector(7 downto 0);
      EOF_A           : in  std_logic;
      K_A1            : out std_logic_vector(7 downto 0);
      K_A2            : out std_logic_vector(7 downto 0);
      K_A3            : out std_logic_vector(7 downto 0);
      K_A4            : out std_logic_vector(7 downto 0);
      K_A5            : out std_logic_vector(7 downto 0);
      K_B1            : out std_logic_vector(7 downto 0);
      K_B2            : out std_logic_vector(7 downto 0);
      K_B3            : out std_logic_vector(7 downto 0);
      K_B4            : out std_logic_vector(7 downto 0);
      K_B5            : out std_logic_vector(7 downto 0);
      K_C1            : out std_logic_vector(7 downto 0);
      K_C2            : out std_logic_vector(7 downto 0);
      K_C3            : out std_logic_vector(7 downto 0);
      K_C4            : out std_logic_vector(7 downto 0);
      K_C5            : out std_logic_vector(7 downto 0);
      K_D1            : out std_logic_vector(7 downto 0);
      K_D2            : out std_logic_vector(7 downto 0);
      K_D3            : out std_logic_vector(7 downto 0);
      K_D4            : out std_logic_vector(7 downto 0);
      K_D5            : out std_logic_vector(7 downto 0);
      K_E1            : out std_logic_vector(7 downto 0);
      K_E2            : out std_logic_vector(7 downto 0);
      K_E3            : out std_logic_vector(7 downto 0);
      K_E4            : out std_logic_vector(7 downto 0);
      K_E5            : out std_logic_vector(7 downto 0);
      SHIFT           : out std_logic_vector(3 downto 0)
    );
  end component;

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

  component colourPicker
    port (
      DATA_IN    : in  std_logic_vector(31 downto 0);
      DATA_OUT   : out std_logic_vector(31 downto 0);
      DVALID_IN  : in  std_logic;
      DVALID_OUT : out std_logic;
      CLOCK      : in  std_logic;
      RESET      : in  std_logic;
      EOL_IN     : in  std_logic;
      EOL_OUT    : out std_logic;
      EOF_IN     : in  std_logic;
      EOF_OUT    : out std_logic
    );
  end component;

  signal SDCLK        : std_logic;  -- DDR SDRAM clock

  signal OUTFIFO_SEL  : std_logic_vector(5 downto 0);
  signal READY_A      : std_logic;
  signal READY_B      : std_logic;
  signal READY_C      : std_logic;
  signal RD_EN        : std_logic;
  signal EMPTY        : std_logic;
  signal EMPTY_v      : std_logic_vector(5 downto 0);
  signal WRITE        : std_logic_vector(5 downto 0);

  signal DVALID_A     : std_logic;
  signal EOL_A        : std_logic;
  signal EOF_A        : std_logic;
  signal DATA_A       : std_logic_vector(31 downto 0);

  signal DVALID_AB    : std_logic;
  signal EOL_AB       : std_logic;
  signal EOF_AB       : std_logic;
  signal DATA_AB      : std_logic_vector(31 downto 0);

  signal DVALID_CP    : std_logic;
  signal EOL_CP       : std_logic;
  signal EOF_CP       : std_logic;
  signal DATA_CP      : std_logic_vector(31 downto 0);

  signal DVALID_B     : std_logic;
  signal EOL_B        : std_logic;
  signal EOF_B        : std_logic;
  signal DATA_B       : std_logic_vector(31 downto 0);

  signal DVALID_C     : std_logic;
  signal EOL_C        : std_logic;
  signal EOF_C        : std_logic;
  signal DATA_C       : std_logic_vector(31 downto 0);

  signal DVALID_D     : std_logic;
  signal EOL_D        : std_logic;
  signal EOF_D        : std_logic;
  signal DATA_D       : std_logic_vector(31 downto 0);

  signal DVALID_E     : std_logic;
  signal DATA_E       : std_logic_vector(31 downto 0);

  signal DVALID_NOT   : std_logic;
  signal EOL_NOT      : std_logic;
  signal EOF_NOT      : std_logic;
  signal DATA_NOT     : std_logic_vector(7 downto 0);

  signal DVALID_ANDK  : std_logic;
  signal EOL_ANDK     : std_logic;
  signal EOF_ANDK     : std_logic;
  signal DATA_ANDK    : std_logic_vector(7 downto 0);

  signal DVALID_RSHK  : std_logic;
  signal EOL_RSHK     : std_logic;
  signal EOF_RSHK     : std_logic;
  signal DATA_RSHK    : std_logic_vector(7 downto 0);

  signal DVALID_LSHK  : std_logic;
  signal EOL_LSHK     : std_logic;
  signal EOF_LSHK     : std_logic;
  signal DATA_LSHK    : std_logic_vector(7 downto 0);

  signal DVALID_MPYK  : std_logic;
  signal EOL_MPYK     : std_logic;
  signal EOF_MPYK     : std_logic;
  signal DATA_MPYK    : std_logic_vector(7 downto 0);

  signal DVALID_SQU   : std_logic;
  signal EOL_SQU      : std_logic;
  signal EOF_SQU      : std_logic;
  signal DATA_SQU     : std_logic_vector(7 downto 0);

  signal DVALID_ADDK  : std_logic;
  signal EOL_ADDK     : std_logic;
  signal EOF_ADDK     : std_logic;
  signal DATA_ADDK    : std_logic_vector(7 downto 0);

  signal DVALID_ADD   : std_logic;
  signal EOL_ADD      : std_logic;
  signal EOF_ADD      : std_logic;
  signal DATA_ADD     : std_logic_vector(7 downto 0);

  signal DVALID_SUB   : std_logic;
  signal EOL_SUB      : std_logic;
  signal EOF_SUB      : std_logic;
  signal DATA_SUB     : std_logic_vector(7 downto 0);

  signal DVALID_MPY   : std_logic;
  signal EOL_MPY      : std_logic;
  signal EOF_MPY      : std_logic;
  signal DATA_MPY     : std_logic_vector(7 downto 0);

  signal DVALID_AND   : std_logic;
  signal EOL_AND      : std_logic;
  signal EOF_AND      : std_logic;
  signal DATA_AND     : std_logic_vector(7 downto 0);

  signal DVALID_OR    : std_logic;
  signal EOL_OR       : std_logic;
  signal EOF_OR       : std_logic;
  signal DATA_OR      : std_logic_vector(7 downto 0);

  signal DVALID_XOR   : std_logic;
  signal EOL_XOR      : std_logic;
  signal EOF_XOR      : std_logic;
  signal DATA_XOR     : std_logic_vector(7 downto 0);

  signal DVALID_XORK  : std_logic;
  signal EOL_XORK     : std_logic;
  signal EOF_XORK     : std_logic;
  signal DATA_XORK    : std_logic_vector(7 downto 0);

  signal DVALID_SUBK  : std_logic;
  signal EOL_SUBK     : std_logic;
  signal EOF_SUBK     : std_logic;
  signal DATA_SUBK    : std_logic_vector(7 downto 0);

  signal DVALID_FILLK : std_logic;
  signal EOL_FILLK    : std_logic;
  signal EOF_FILLK    : std_logic;
  signal DATA_FILLK   : std_logic_vector(7 downto 0);

  signal DVALID_ORK   : std_logic;
  signal EOL_ORK      : std_logic;
  signal EOF_ORK      : std_logic;
  signal DATA_ORK     : std_logic_vector(7 downto 0);

  signal DVALID_CONV  : std_logic;
  signal EOL_CONV     : std_logic;
  signal EOF_CONV     : std_logic;
  signal DATA_CONV    : std_logic_vector(7 downto 0);

  signal DVALID_RAMP  : std_logic;
  signal EOL_RAMP     : std_logic;
  signal EOF_RAMP     : std_logic;
  signal DATA_RAMP    : std_logic_vector(7 downto 0);

  signal PORT_B_ADD_REQ : std_logic;
  signal PORT_B_SUB_REQ : std_logic;
  signal PORT_B_MPY_REQ : std_logic;
  signal PORT_B_AND_REQ : std_logic;
  signal PORT_B_OR_REQ  : std_logic;
  signal PORT_B_XOR_REQ : std_logic;

  signal OUT_FIFO_COUNT    : std_logic_vector(4 downto 0);
  signal OUT_FIFO_RD_COUNT : std_logic_vector(4 downto 0);

  signal BUF_WR_FF         : std_logic;
  signal BUF_WR_EF         : std_logic;
  signal BUF_RD_AF         : std_logic;

  signal RX                : std_logic;
  signal TX                : std_logic;

  signal PIXEL_TOTAL       : std_logic_vector(11 downto 0);
  signal LINE_TOTAL        : std_logic_vector(11 downto 0);
  signal FIRST_PIXEL       : std_logic_vector(11 downto 0);
  signal LAST_PIXEL        : std_logic_vector(11 downto 0);
  signal FIRST_LINE        : std_logic_vector(11 downto 0);
  signal LAST_LINE         : std_logic_vector(11 downto 0);

  signal ACTIVE            : std_logic_vector(3 downto 0);
  signal BIT_SEL           : std_logic_vector(1 downto 0);
  signal CP_SEL            : std_logic;
  signal CONTINUOUS        : std_logic;
  signal ODD_ONLY          : std_logic;
  signal LOAD              : std_logic;
  signal FRAMES            : std_logic_vector(3 downto 0);
  signal AUTO_RES          : std_logic;
  signal POLARITY          : std_logic;
  signal USE_DVAL          : std_logic;
  signal CAM_INPUTS        : std_logic_vector(3 downto 0);

  signal START_PIXEL       : std_logic_vector(11 downto 0);
  signal STOP_PIXEL        : std_logic_vector(11 downto 0);
  signal START_LINE        : std_logic_vector(11 downto 0);
  signal STOP_LINE         : std_logic_vector(11 downto 0);

  signal IMAGE_BLOCK_SEL   : std_logic_vector(7 downto 0);
  signal PIXEL_CLOCK       : std_logic;
  signal ROI_VALID         : std_logic;
  signal OUT_FIFO_DATA     : std_logic_vector(31 downto 0);
  signal Sync              : std_logic;
  signal OUT_FIFOA_WR      : std_logic;
  signal CAT1_CONST        : std_logic_vector(7 downto 0);
  signal SDRAM_WR_EN       : std_logic;
  signal PORT_B_REQ        : std_logic;
  signal READ_SDRAM        : std_logic;
  signal count_rd_en       : std_logic;

  signal WRITE_ONCE        : std_logic;
  signal WRITE_IMAGE       : std_logic;

  signal WR_FIFO_AF        : std_logic;
  signal WR_FIFO_WR        : std_logic;
  signal WR_FIFO_EF        : std_logic;
  signal RD_FIFO_AF        : std_logic;
  signal RD_FIFO_AE        : std_logic;
  signal RD_FIFO_EF        : std_logic;

  signal SDRAM_WR_AEN      : std_logic;

  signal WR_FIFO_DOUT      : std_logic_vector(31 downto 0);
  signal WR_ADDRESS        : std_logic_vector(22 downto 0);
  signal WR_COUNT          : std_logic_vector(1 downto 0);
  signal WR_FIFO_RD        : std_logic;

  signal RD_FIFO_DIN       : std_logic_vector(31 downto 0);
  signal RD_ADDRESS        : std_logic_vector(22 downto 0);
  signal RD_FIFO_WR        : std_logic;
  signal READ_ZERO         : std_logic;
  signal RISE_FALL         : std_logic;

  signal SDRAM_WR_BUFFER_RD    : std_logic;
  signal SDRAM_WR_BUFFER_EF    : std_logic;
  signal SDRAM_WR_BUFFER_DATA  : std_logic_vector(31 downto 0);
  signal SDRAM_RD_BUFFER_AF    : std_logic;
  signal SDRAM_RD_BUFFER_WR    : std_logic;
  signal SDRAM_RD_BUFFER_RD    : std_logic;
  signal SDRAM_RD_BUFFER_DATA  : std_logic_vector(31 downto 0);

  signal PORT_B_DATA           : std_logic_vector(31 downto 0);
  signal FIFO_RST              : std_logic_vector(1 downto 0);
  signal WR_FIFO_WR_CT         : std_logic_vector(4 downto 0);
  signal RD_FIFO_WR_CT         : std_logic_vector(4 downto 0);
  signal IMAGE_BLOCK_CURRENT_A : std_logic_vector(7 downto 0);
  signal IMAGE_BLOCK_CURRENT   : std_logic_vector(7 downto 0);
  signal SDRAM_rd_count        : std_logic_vector(17 downto 0);
  signal OUT_FIFO_A_RD         : std_logic;
  signal OUT_FIFO_A_RD_DEL     : std_logic;
  signal OUT_FIFO_A_DATA       : std_logic_vector(31 downto 0);
  signal SHIFT                 : std_logic_vector(3 downto 0);

  signal K_A1                 : std_logic_vector(17 downto 0);
  signal K_A2                 : std_logic_vector(17 downto 0);
  signal K_A3                 : std_logic_vector(17 downto 0);
  signal K_A4                 : std_logic_vector(17 downto 0);
  signal K_A5                 : std_logic_vector(17 downto 0);
  signal K_B1                 : std_logic_vector(17 downto 0);
  signal K_B2                 : std_logic_vector(17 downto 0);
  signal K_B3                 : std_logic_vector(17 downto 0);
  signal K_B4                 : std_logic_vector(17 downto 0);
  signal K_B5                 : std_logic_vector(17 downto 0);
  signal K_C1                 : std_logic_vector(17 downto 0);
  signal K_C2                 : std_logic_vector(17 downto 0);
  signal K_C3                 : std_logic_vector(17 downto 0);
  signal K_C4                 : std_logic_vector(17 downto 0);
  signal K_C5                 : std_logic_vector(17 downto 0);
  signal K_D1                 : std_logic_vector(17 downto 0);
  signal K_D2                 : std_logic_vector(17 downto 0);
  signal K_D3                 : std_logic_vector(17 downto 0);
  signal K_D4                 : std_logic_vector(17 downto 0);
  signal K_D5                 : std_logic_vector(17 downto 0);
  signal K_E1                 : std_logic_vector(17 downto 0);
  signal K_E2                 : std_logic_vector(17 downto 0);
  signal K_E3                 : std_logic_vector(17 downto 0);
  signal K_E4                 : std_logic_vector(17 downto 0);
  signal K_E5                 : std_logic_vector(17 downto 0);
  signal K_A1_TEMP            : std_logic_vector(7 downto 0);
  signal K_A2_TEMP            : std_logic_vector(7 downto 0);
  signal K_A3_TEMP            : std_logic_vector(7 downto 0);
  signal K_A4_TEMP            : std_logic_vector(7 downto 0);
  signal K_A5_TEMP            : std_logic_vector(7 downto 0);
  signal K_B1_TEMP            : std_logic_vector(7 downto 0);
  signal K_B2_TEMP            : std_logic_vector(7 downto 0);
  signal K_B3_TEMP            : std_logic_vector(7 downto 0);
  signal K_B4_TEMP            : std_logic_vector(7 downto 0);
  signal K_B5_TEMP            : std_logic_vector(7 downto 0);
  signal K_C1_TEMP            : std_logic_vector(7 downto 0);
  signal K_C2_TEMP            : std_logic_vector(7 downto 0);
  signal K_C3_TEMP            : std_logic_vector(7 downto 0);
  signal K_C4_TEMP            : std_logic_vector(7 downto 0);
  signal K_C5_TEMP            : std_logic_vector(7 downto 0);
  signal K_D1_TEMP            : std_logic_vector(7 downto 0);
  signal K_D2_TEMP            : std_logic_vector(7 downto 0);
  signal K_D3_TEMP            : std_logic_vector(7 downto 0);
  signal K_D4_TEMP            : std_logic_vector(7 downto 0);
  signal K_D5_TEMP            : std_logic_vector(7 downto 0);
  signal K_E1_TEMP            : std_logic_vector(7 downto 0);
  signal K_E2_TEMP            : std_logic_vector(7 downto 0);
  signal K_E3_TEMP            : std_logic_vector(7 downto 0);
  signal K_E4_TEMP            : std_logic_vector(7 downto 0);
  signal K_E5_TEMP            : std_logic_vector(7 downto 0);

begin

  -------------------------------------------------------------
  -- Camera Link component : input of camera-link data and
  -- control information

  CAM_CTRL <= CAM_INPUTS;

  iCLINK : CLINK
    generic map (
      LFreq_Deserialiser => Use_Low_Freq_Deserialiser )
    port map (
      RESET       => RESET,
      CAM_CLK     => CAM_CLK,
      CAM_DATA    => CAM_DATA,
      POLARITY    => POLARITY,
      USE_DVAL    => USE_DVAL,
      BIT_SEL     => BIT_SEL,
      PIXEL_CLOCK => PIXEL_CLOCK,
      DVALID_OUT  => DVALID_A,
      EOL_OUT     => EOL_A,
      EOF_OUT     => EOF_A,
      DATA_OUT    => DATA_A,
      ACTIVE      => ACTIVE );

  -------------------------------------------------------------
  -- AUTO_ROI component : automatic region of interest detection

  iAUTO_ROI : AUTO_ROI
    port map (
      RESET       => AUTO_RES,
      PIXEL_CLOCK => PIXEL_CLOCK,
      DVALID_IN   => DVALID_A,
      EOL_IN      => EOL_A,
      EOF_IN      => EOF_A,
      DATA_IN     => DATA_A,
      FIRST_PIXEL => FIRST_PIXEL,
      LAST_PIXEL  => LAST_PIXEL,
      FIRST_LINE  => FIRST_LINE,
      LAST_LINE   => LAST_LINE,
      PIXEL_TOTAL => PIXEL_TOTAL,
      LINE_TOTAL  => LINE_TOTAL,
      ROI_VALID   => ROI_VALID );

-------------------------------------------------------------
-- colourPicker component : allows colour cameras with Bayer
-- outputs to be used - picks only green pixels from data

  iPICKER : colourPicker
    port map (
      DATA_IN    => DATA_A,
      DATA_OUT   => DATA_CP,
      DVALID_IN  => DVALID_A,
      DVALID_OUT => DVALID_CP,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_A,
      EOL_OUT    => EOL_CP,
      EOF_IN     => EOF_A,
      EOF_OUT    => EOF_CP );

  DATA_AB   <= DATA_A   when CP_SEL='0' else DATA_CP;
  DVALID_AB <= DVALID_A when CP_SEL='0' else DVALID_CP;
  EOL_AB    <= EOL_A    when CP_SEL='0' else EOL_CP;
  EOF_AB    <= EOF_A    when CP_SEL='0' else EOF_CP;

-------------------------------------------------------------
-- ROI component : region of interest applied to data stream
-- output from the CLINK component

  iROI : ROI
    port map (
      RESET       => RESET,
      PIXEL_CLOCK => PIXEL_CLOCK,
      ODD_ONLY    => ODD_ONLY,
      DVALID_IN   => DVALID_AB,
      EOL_IN      => EOL_AB,
      EOF_IN      => EOF_AB,
      DVALID_OUT  => DVALID_B,
      EOL_OUT     => EOL_B,
      EOF_OUT     => EOF_B,
      START_PIXEL => START_PIXEL,
      STOP_PIXEL  => STOP_PIXEL,
      START_LINE  => START_LINE,
      STOP_LINE   => STOP_LINE,
      DATA_IN     => DATA_AB,
      DATA_OUT    => DATA_B );

  -------------------------------------------------------------
  -- FRAME_CONTROL component : frame output control applied to
  -- data stream output from the ROI component

  iFRAME_CONTROL : FRAME_CONTROL
    port map (
      RESET       => RESET,
      PIXEL_CLOCK => PIXEL_CLOCK,
      CONTINUOUS  => CONTINUOUS,
      DVALID_IN   => DVALID_B,
      EOL_IN      => EOL_B,
      EOF_IN      => EOF_B,
      DVALID_OUT  => DVALID_C,
      EOL_OUT     => EOL_C,
      EOF_OUT     => EOF_C,
      LOAD        => LOAD,
      FRAMES      => FRAMES,
      DATA_IN     => DATA_B,
      DATA_OUT    => DATA_C );

  ----------------------------------------------------------
  -- Fixed co-efficient operator components

  iinvert : invert
    generic map (
      Synchronous => False,
      N           => 8 )
    port map (
      DATA_IN    => DATA_C(7 downto 0),
      DATA_OUT   => DATA_NOT,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_NOT,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_NOT,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_NOT );

  iANDK : ANDK
    generic map (
      Synchronous => False,
      N           => 8 )
    port map (
      DATA_IN    => DATA_C(7 downto 0),
      DATA_OUT   => DATA_ANDK,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_ANDK,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_ANDK,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_ANDK,
      K_IN       => CAT1_CONST );

  iADDK : ADDK
    generic map (
      Synchronous => True,
      N           => 8 )
    port map (
      DATA_IN    => DATA_C(7 downto 0),
      DATA_OUT   => DATA_ADDK,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_ADDK,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_ADDK,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_ADDK,
      K_IN       => CAT1_CONST );

  iORK : ORK
    generic map (
      Synchronous => False,
      N           => 8 )
    port map (
      DATA_IN    => DATA_C(7 downto 0),
      DATA_OUT   => DATA_ORK,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_ORK,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_ORK,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_ORK,
      K_IN       => CAT1_CONST );

  iXORK : XORK
    generic map (
      Synchronous => False,
      N           => 8 )
    port map (
      DATA_IN    => DATA_C(7 downto 0),
      DATA_OUT   => DATA_XORK,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_XORK,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_XORK,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_XORK,
      K_IN       => CAT1_CONST );

  iFillRamp : FILLRAMP
    generic map (
      N          => 8 )
    port map (
      DATA_OUT   => DATA_RAMP,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_RAMP,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_RAMP,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_RAMP,
      K_IN       => CAT1_CONST );

  iFILLK : FILLK
    generic map (
      N          => 8 )
    port map (
      DATA_OUT   => DATA_FILLK,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_FILLK,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_FILLK,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_FILLK,
      K_IN       => CAT1_CONST );

  iSUBK : SUBK
    generic map (
      Synchronous => False,
      StopAtZero  => True,
      N           => 8 )
    port map (
      DATA_IN    => DATA_C(7 downto 0),
      DATA_OUT   => DATA_SUBK,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_SUBK,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_SUBK,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_SUBK,
      K_IN       => CAT1_CONST );

  iMPYK : MPYK
    generic map (
      Synchronous => True,
      N           => 8 )
    port map (
      DATA_IN    => DATA_C(7 downto 0),
      DATA_OUT   => DATA_MPYK,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_MPYK,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_MPYK,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_MPYK,
      K_IN       => CAT1_CONST );

  iSQUARE : SQUARE
    generic map (
      Synchronous => True,
      N           => 8 )
    port map (
      DATA_IN    => DATA_C(7 downto 0),
      DATA_OUT   => DATA_SQU,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_SQU,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_SQU,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_SQU );

  iLSHK : LSHK
    generic map (
      Synchronous  => True,
      FillWithOnes => False,
      N            => 8 )
    port map (
      DATA_IN    => DATA_C(7 downto 0),
      DATA_OUT   => DATA_LSHK,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_LSHK,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_LSHK,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_LSHK,
      K_IN       => CAT1_CONST );

  iRSHK : RSHK
    generic map (
      Synchronous  => True,
      FillWithOnes => False,
      N            => 8 )
    port map (
      DATA_IN    => DATA_C(7 downto 0),
      DATA_OUT   => DATA_RSHK,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_RSHK,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_RSHK,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_RSHK,
      K_IN       => CAT1_CONST );

  ---------------------------------------------------------------------------
  -- Variable coefficient operator functions

  iADD : ADDImage
    generic map (
      N          => 8 )
    port map (
      DATA_A     => DATA_C(7 downto 0),
      DATA_OUT   => DATA_ADD,
      DVALID_A   => DVALID_C,
      DVALID_OUT => DVALID_ADD,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_ADD,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_ADD,
      REQ_PIXEL  => PORT_B_ADD_REQ,
      DATA_B     => PORT_B_DATA(7 downto 0));

  iAND : ANDImage
    generic map (
      N          => 8 )
    port map (
      DATA_A     => DATA_C(7 downto 0),
      DATA_OUT   => DATA_AND,
      DVALID_A   => DVALID_C,
      DVALID_OUT => DVALID_AND,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_AND,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_AND,
      REQ_PIXEL  => PORT_B_AND_REQ,
      DATA_B     => PORT_B_DATA(7 downto 0));

  iOR : ORImage
    generic map (
      N          => 8 )
    port map (
      DATA_A     => DATA_C(7 downto 0),
      DATA_OUT   => DATA_OR,
      DVALID_A   => DVALID_C,
      DVALID_OUT => DVALID_OR,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_OR,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_OR,
      REQ_PIXEL  => PORT_B_OR_REQ,
      DATA_B     => PORT_B_DATA(7 downto 0));

  iXOR : XORImage
    generic map (
      N          => 8 )
    port map (
     DATA_A     => DATA_C(7 downto 0),
     DATA_OUT   => DATA_XOR,
     DVALID_A   => DVALID_C,
     DVALID_OUT => DVALID_XOR,
     CLOCK      => PIXEL_CLOCK,
     RESET      => RESET,
     EOL_IN     => EOL_C,
     EOL_OUT    => EOL_XOR,
     EOF_IN     => EOF_C,
     EOF_OUT    => EOF_XOR,
     REQ_PIXEL  => PORT_B_XOR_REQ,
     DATA_B     => PORT_B_DATA(7 downto 0));

  iSUBImage : SUBImage
    generic map (
      StopAtZero => True,
      N          => 8 )
    port map (
      DATA_A     => DATA_C(7 downto 0),
      DATA_OUT   => DATA_SUB,
      DVALID_A   => DVALID_C,
      DVALID_OUT => DVALID_SUB,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_SUB,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_SUB,
      REQ_PIXEL  => PORT_B_SUB_REQ,
      DATA_B     => PORT_B_DATA(7 downto 0));

  iMPYImage : MPYImage
    generic map (
      N          => 8 )
    port map (
      DATA_A     => DATA_C(7 downto 0),
      DATA_OUT   => DATA_MPY,
      DVALID_A   => DVALID_C,
      DVALID_OUT => DVALID_MPY,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_MPY,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_MPY,
      REQ_PIXEL  => PORT_B_MPY_REQ,
      DATA_B     => PORT_B_DATA(7 downto 0));

  process(IMAGE_BLOCK_SEL)
  begin
    case IMAGE_BLOCK_SEL is
      when "00001110" => PORT_B_REQ <= PORT_B_ADD_REQ;
      when "00001111" => PORT_B_REQ <= PORT_B_AND_REQ;
      when "00010000" => PORT_B_REQ <= PORT_B_OR_REQ;
      when "00010001" => PORT_B_REQ <= PORT_B_SUB_REQ;
      when "00010010" => PORT_B_REQ <= PORT_B_XOR_REQ;
      when "00010011" => PORT_B_REQ <= PORT_B_MPY_REQ;
      when others =>     PORT_B_REQ <= '0';
    end case;
  end process;

  ----------------------------------------------------------------------------
  --SDRAM handling for CAT2 functions
  ----------------------------------------------------------------------------

  SDRAM_WR_EN <= '1' when ((WRITE_IMAGE='1') and (DVALID_C='1')) else '0';

  process(PIXEL_CLOCK, RESET)
  begin
    if RESET = '1' then
      WRITE_IMAGE <= '0';
      WRITE_ONCE  <= '0';
    elsif rising_edge(PIXEL_CLOCK) then
      if (EOF_C = '1' and WRITE_IMAGE = '0'
           and WRITE_ONCE = '0' and IMAGE_BLOCK_SEL = "00001101") then
        WRITE_IMAGE <= '1';
      elsif (EOF_C = '1' and WRITE_IMAGE = '1') then
        WRITE_IMAGE <= '0';
        WRITE_ONCE  <= '1';
      end if;
      if IMAGE_BLOCK_SEL /= "00001101" then
        WRITE_ONCE <= '0';
      end if;
    end if;
  end process;

  --SDRAM FIFO work around fifo, decouples clocks
  iSDRAM_WR_BUFFER : fifo15x32
    port map (
      din          => DATA_C,
      wr_en        => SDRAM_WR_EN,
      wr_clk       => PIXEL_CLOCK,
      rd_en        => SDRAM_WR_BUFFER_RD,
      rd_clk       => SDCLK,
      ainit        => FIFO_RST(0),
      dout         => SDRAM_WR_BUFFER_DATA,
      full         => open,
      empty        => SDRAM_WR_BUFFER_EF,
      almost_full  => open,
      almost_empty => open );

  -------------------------------------------------------------
  -- SDRAM Write Interface Data FIFO

  SDCLK <= PIXEL_CLOCK;

  DDR_A_USER_CLK <= PIXEL_CLOCK;
  DDR_A_USER_RST <= '0';

  SDRAM_WR_BUFFER_RD <= (NOT SDRAM_WR_BUFFER_EF) AND WR_FIFO_AF;

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

  WR_FIFO_AF <= '0' when WR_FIFO_WR_CT(4 downto 1)="0000" else '1';

  iLoad_SDRAM_FIFO : FIFO16x32
    port map (
      RESET    => FIFO_RST(0),
      CLOCK    => SDCLK,
      DIN      => SDRAM_WR_BUFFER_DATA,
      WR_EN    => WR_FIFO_WR,
      RD_EN    => WR_FIFO_RD,
      DOUT     => WR_FIFO_DOUT,
      FULL     => open,
      EMPTY    => WR_FIFO_EF,
      WR_COUNT => WR_FIFO_WR_CT,
      RD_COUNT => open );

  DDR_A_WR_RISE_WEN <= WR_FIFO_RD AND (NOT WR_COUNT(0));
  DDR_A_WR_FALL_WEN <= WR_FIFO_RD AND (    WR_COUNT(0));
  DDR_A_WR_DM_WEN   <= WR_FIFO_RD AND (    WR_COUNT(0));

  WR_FIFO_RD <= WR_FIFO_EF AND (NOT DDR_A_WR_RISE_AF) AND (NOT DDR_A_WR_FALL_AF) AND
                               (NOT DDR_A_WR_DM_AF);

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

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

  DDR_A_WR_ADDR_WEN <= WR_FIFO_RD AND WR_COUNT(1) AND WR_COUNT(0);

  --Create SDRAM address
  DDR_A_WR_ADDR <= WR_ADDRESS & "00";

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      WR_ADDRESS <= (others=>'0');
    elsif rising_edge(SDCLK) then
      if SDRAM_WR_AEN='1' then
        WR_ADDRESS <= (others=>'0');
      elsif (WR_FIFO_RD='1' and WR_COUNT="11") then
        WR_ADDRESS <= WR_ADDRESS + 1;
      end if;
    end if;
  end process;

  -------------------------------------------------------------
  -- DDR SDRAM Read Interface Data FIFO

  DDR_A_RD_RISE_REN <= (NOT DDR_A_RD_RISE_EF) AND (NOT RISE_FALL) AND RD_FIFO_AF;
  DDR_A_RD_FALL_REN <= (NOT DDR_A_RD_FALL_EF) AND (    RISE_FALL) AND RD_FIFO_AF;

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      RISE_FALL <= '0';
    elsif rising_edge(SDCLK) then
      RISE_FALL <= '0';
      if (RISE_FALL='0' and DDR_A_RD_RISE_EF='0' and RD_FIFO_AF='1') or
         (RISE_FALL='1' and (DDR_A_RD_FALL_EF='1' or RD_FIFO_AF='0')) then
        RISE_FALL <= '1';
      end if;
    end if;
  end process;

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      RD_FIFO_WR <= '0';
    elsif rising_edge(SDCLK) then
      RD_FIFO_WR <= '0';
      if (RISE_FALL='0' and DDR_A_RD_RISE_EF='0' and RD_FIFO_AF='1') or
         (RISE_FALL='1' and DDR_A_RD_FALL_EF='0' and RD_FIFO_AF='1') then
        RD_FIFO_WR <= '1';
      end if;
    end if;
  end process;

  RD_FIFO_DIN <= DDR_A_RD_DATA(31 downto 0) when RISE_FALL='1' else DDR_A_RD_DATA(63 downto 32);

  DDR_A_RD_ADDR_WEN <= (NOT DDR_A_RD_ADDR_FF) AND (NOT READ_ZERO) AND RD_FIFO_AF;

  DDR_A_RD_ADDR <= RD_ADDRESS & "00";

  process(RESET, SDCLK)
  begin
    if RESET='1' then
      RD_ADDRESS <= (others=>'0');
    elsif rising_edge(SDCLK) then
      if EOF_C='1' then
        RD_ADDRESS <= (others=>'0');
      elsif (DDR_A_RD_ADDR_FF='0' and READ_ZERO='0' and RD_FIFO_AF='1') then
        RD_ADDRESS <= RD_ADDRESS + 1;
      end if;
    end if;
  end process;

  --Process sets SDRAM address and selects whether SDRAM is read or not
  process(RESET, SDCLK)
  begin
    if RESET='1' then
      SDRAM_WR_AEN <= '0';
      IMAGE_BLOCK_CURRENT_A <= (others=>'0');
      READ_SDRAM   <= '0';
    elsif rising_edge(SDCLK) then
      SDRAM_WR_AEN <= '0';
      if IMAGE_BLOCK_CURRENT_A /= IMAGE_BLOCK_SEL then
        SDRAM_WR_AEN  <= '1';
        READ_SDRAM <= '0';
        if (IMAGE_BLOCK_SEL = "00001110" or IMAGE_BLOCK_SEL = "00001111"
         or IMAGE_BLOCK_SEL = "00010000" or IMAGE_BLOCK_SEL = "00010001"
         or IMAGE_BLOCK_SEL = "00010010" or IMAGE_BLOCK_SEL = "00010011") then
          READ_SDRAM <= '1';
        end if;
        IMAGE_BLOCK_CURRENT_A <= IMAGE_BLOCK_SEL;
       end if;
    end if;
  end process;

  -- SDRAM Read Interface Data FIFO
  process(SDCLK, RESET)
  begin
    if RESET='1' then
      SDRAM_rd_count <= (others=>'0');
    elsif rising_edge(SDCLK) then
      if (IMAGE_BLOCK_CURRENT_A /= IMAGE_BLOCK_SEL or EOF_C='1') then
        SDRAM_rd_count <= (others=>'0');
      elsif (RD_FIFO_WR='1' and count_rd_en='1') then
        SDRAM_rd_count <= SDRAM_rd_count + 1;
      end if;
     end if;
  end process;

  count_rd_en <= '0' when SDRAM_rd_count="100100000000000000" else '1';

  READ_ZERO <= NOT (count_rd_en AND READ_SDRAM);

  process(SDCLK, RESET)
  begin
    if RESET = '1' then
      FIFO_RST <= "11";
   elsif rising_edge(SDCLK) then
      FIFO_RST <= '0' & FIFO_RST(1);
      if((IMAGE_BLOCK_CURRENT /= IMAGE_BLOCK_SEL) or (EOF_C='1')) then
        FIFO_RST <= "11";
        IMAGE_BLOCK_CURRENT <= IMAGE_BLOCK_SEL;
      end if;
    end if;
  end process;

  SDRAM_RD_BUFFER_WR <= RD_FIFO_WR AND count_rd_en;

  portBfifo : FIFO16x32
    port map (
      RESET    => FIFO_RST(0),
      CLOCK    => SDCLK,
      DIN      => RD_FIFO_DIN,
      WR_EN    => SDRAM_RD_BUFFER_WR,
      RD_EN    => SDRAM_RD_BUFFER_RD,
      DOUT     => SDRAM_RD_BUFFER_DATA,
      FULL     => open,
      EMPTY    => RD_FIFO_EF,
      WR_COUNT => RD_FIFO_WR_CT,
      RD_COUNT => open );

  -- Indicate almost full when 3 words to write or less
  RD_FIFO_AF <= '0' when RD_FIFO_WR_CT(4 downto 2)="000" else '1';

  SDRAM_RD_BUFFER_RD <= (NOT SDRAM_RD_BUFFER_AF) AND RD_FIFO_EF;

  -- FIFO to decouple clocks
  iSDRAM_RD_BUFFER : fifo15x32
    port map (
      din          => SDRAM_RD_BUFFER_DATA,
      wr_en        => SDRAM_RD_BUFFER_RD,
      wr_clk       => SDCLK,
      rd_en        => PORT_B_REQ,
      rd_clk       => PIXEL_CLOCK,
      ainit        => FIFO_RST(0),
      dout         => PORT_B_DATA,
      full         => open,
      empty        => open,
      almost_full  => SDRAM_RD_BUFFER_AF,
      almost_empty => open );

  ----------------------------------------------------------------------
  --Convolution functions

  K_A1 <= K_A1_TEMP(7) & K_A1_TEMP(7) & K_A1_TEMP(7) & K_A1_TEMP(7) &
          K_A1_TEMP(7) & K_A1_TEMP(7) & K_A1_TEMP(7) & K_A1_TEMP(7) &
          K_A1_TEMP(7) & K_A1_TEMP(7) & K_A1_TEMP(7) & K_A1_TEMP(6 downto 0);

  K_A2 <= K_A2_TEMP(7) & K_A2_TEMP(7) & K_A2_TEMP(7) & K_A2_TEMP(7) &
          K_A2_TEMP(7) & K_A2_TEMP(7) & K_A2_TEMP(7) & K_A2_TEMP(7) &
          K_A2_TEMP(7) & K_A2_TEMP(7) & K_A2_TEMP(7) & K_A2_TEMP(6 downto 0);

  K_A3 <= K_A3_TEMP(7) & K_A3_TEMP(7) & K_A3_TEMP(7) & K_A3_TEMP(7) &
          K_A3_TEMP(7) & K_A3_TEMP(7) & K_A3_TEMP(7) & K_A3_TEMP(7) &
          K_A3_TEMP(7) & K_A3_TEMP(7) & K_A3_TEMP(7) & K_A3_TEMP(6 downto 0);

  K_A4 <= K_A4_TEMP(7) & K_A4_TEMP(7) & K_A4_TEMP(7) & K_A4_TEMP(7) &
          K_A4_TEMP(7) & K_A4_TEMP(7) & K_A4_TEMP(7) & K_A4_TEMP(7) &
          K_A4_TEMP(7) & K_A4_TEMP(7) & K_A4_TEMP(7) & K_A4_TEMP(6 downto 0);

  K_A5 <= K_A5_TEMP(7) & K_A5_TEMP(7) & K_A5_TEMP(7) & K_A5_TEMP(7) &
          K_A5_TEMP(7) & K_A5_TEMP(7) & K_A5_TEMP(7) & K_A5_TEMP(7) &
          K_A5_TEMP(7) & K_A5_TEMP(7) & K_A5_TEMP(7) & K_A5_TEMP(6 downto 0);

  K_B1 <= K_B1_TEMP(7) & K_B1_TEMP(7) & K_B1_TEMP(7) & K_B1_TEMP(7) &
          K_B1_TEMP(7) & K_B1_TEMP(7) & K_B1_TEMP(7) & K_B1_TEMP(7) &
          K_B1_TEMP(7) & K_B1_TEMP(7) & K_B1_TEMP(7) & K_B1_TEMP(6 downto 0);

  K_B2 <= K_B2_TEMP(7) & K_B2_TEMP(7) & K_B2_TEMP(7) & K_B2_TEMP(7) &
          K_B2_TEMP(7) & K_B2_TEMP(7) & K_B2_TEMP(7) & K_B2_TEMP(7) &
          K_B2_TEMP(7) & K_B2_TEMP(7) & K_B2_TEMP(7) & K_B2_TEMP(6 downto 0);

  K_B3 <= K_B3_TEMP(7) & K_B3_TEMP(7) & K_B3_TEMP(7) & K_B3_TEMP(7) &
          K_B3_TEMP(7) & K_B3_TEMP(7) & K_B3_TEMP(7) & K_B3_TEMP(7) &
          K_B3_TEMP(7) & K_B3_TEMP(7) & K_B3_TEMP(7) & K_B3_TEMP(6 downto 0);

  K_B4 <= K_B4_TEMP(7) & K_B4_TEMP(7) & K_B4_TEMP(7) & K_B4_TEMP(7) &
          K_B4_TEMP(7) & K_B4_TEMP(7) & K_B4_TEMP(7) & K_B4_TEMP(7) &
          K_B4_TEMP(7) & K_B4_TEMP(7) & K_B4_TEMP(7) & K_B4_TEMP(6 downto 0);

  K_B5 <= K_B5_TEMP(7) & K_B5_TEMP(7) & K_B5_TEMP(7) & K_B5_TEMP(7) &
          K_B5_TEMP(7) & K_B5_TEMP(7) & K_B5_TEMP(7) & K_B5_TEMP(7) &
          K_B5_TEMP(7) & K_B5_TEMP(7) & K_B5_TEMP(7) & K_B5_TEMP(6 downto 0);

  K_C1 <= K_C1_TEMP(7) & K_C1_TEMP(7) & K_C1_TEMP(7) & K_C1_TEMP(7) &
          K_C1_TEMP(7) & K_C1_TEMP(7) & K_C1_TEMP(7) & K_C1_TEMP(7) &
          K_C1_TEMP(7) & K_C1_TEMP(7) & K_C1_TEMP(7) & K_C1_TEMP(6 downto 0);

  K_C2 <= K_C2_TEMP(7) & K_C2_TEMP(7) & K_C2_TEMP(7) & K_C2_TEMP(7) &
          K_C2_TEMP(7) & K_C2_TEMP(7) & K_C2_TEMP(7) & K_C2_TEMP(7) &
          K_C2_TEMP(7) & K_C2_TEMP(7) & K_C2_TEMP(7) & K_C2_TEMP(6 downto 0);

  K_C3 <= K_C3_TEMP(7) & K_C3_TEMP(7) & K_C3_TEMP(7) & K_C3_TEMP(7) &
          K_C3_TEMP(7) & K_C3_TEMP(7) & K_C3_TEMP(7) & K_C3_TEMP(7) &
          K_C3_TEMP(7) & K_C3_TEMP(7) & K_C3_TEMP(7) & K_C3_TEMP(6 downto 0);

  K_C4 <= K_C4_TEMP(7) & K_C4_TEMP(7) & K_C4_TEMP(7) & K_C4_TEMP(7) &
          K_C4_TEMP(7) & K_C4_TEMP(7) & K_C4_TEMP(7) & K_C4_TEMP(7) &
          K_C4_TEMP(7) & K_C4_TEMP(7) & K_C4_TEMP(7) & K_C4_TEMP(6 downto 0);

  K_C5 <= K_C5_TEMP(7) & K_C5_TEMP(7) & K_C5_TEMP(7) & K_C5_TEMP(7) &
          K_C5_TEMP(7) & K_C5_TEMP(7) & K_C5_TEMP(7) & K_C5_TEMP(7) &
          K_C5_TEMP(7) & K_C5_TEMP(7) & K_C5_TEMP(7) & K_C5_TEMP(6 downto 0);

  K_D1 <= K_D1_TEMP(7) & K_D1_TEMP(7) & K_D1_TEMP(7) & K_D1_TEMP(7) &
          K_D1_TEMP(7) & K_D1_TEMP(7) & K_D1_TEMP(7) & K_D1_TEMP(7) &
          K_D1_TEMP(7) & K_D1_TEMP(7) & K_D1_TEMP(7) & K_D1_TEMP(6 downto 0);

  K_D2 <= K_D2_TEMP(7) & K_D2_TEMP(7) & K_D2_TEMP(7) & K_D2_TEMP(7) &
          K_D2_TEMP(7) & K_D2_TEMP(7) & K_D2_TEMP(7) & K_D2_TEMP(7) &
          K_D2_TEMP(7) & K_D2_TEMP(7) & K_D2_TEMP(7) & K_D2_TEMP(6 downto 0);

  K_D3 <= K_D3_TEMP(7) & K_D3_TEMP(7) & K_D3_TEMP(7) & K_D3_TEMP(7) &
          K_D3_TEMP(7) & K_D3_TEMP(7) & K_D3_TEMP(7) & K_D3_TEMP(7) &
          K_D3_TEMP(7) & K_D3_TEMP(7) & K_D3_TEMP(7) & K_D3_TEMP(6 downto 0);

  K_D4 <= K_D4_TEMP(7) & K_D4_TEMP(7) & K_D4_TEMP(7) & K_D4_TEMP(7) &
          K_D4_TEMP(7) & K_D4_TEMP(7) & K_D4_TEMP(7) & K_D4_TEMP(7) &
          K_D4_TEMP(7) & K_D4_TEMP(7) & K_D4_TEMP(7) & K_D4_TEMP(6 downto 0);

  K_D5 <= K_D5_TEMP(7) & K_D5_TEMP(7) & K_D5_TEMP(7) & K_D5_TEMP(7) &
          K_D5_TEMP(7) & K_D5_TEMP(7) & K_D5_TEMP(7) & K_D5_TEMP(7) &
          K_D5_TEMP(7) & K_D5_TEMP(7) & K_D5_TEMP(7) & K_D5_TEMP(6 downto 0);

  K_E1 <= K_E1_TEMP(7) & K_E1_TEMP(7) & K_E1_TEMP(7) & K_E1_TEMP(7) &
          K_E1_TEMP(7) & K_E1_TEMP(7) & K_E1_TEMP(7) & K_E1_TEMP(7) &
          K_E1_TEMP(7) & K_E1_TEMP(7) & K_E1_TEMP(7) & K_E1_TEMP(6 downto 0);

  K_E2 <= K_E2_TEMP(7) & K_E2_TEMP(7) & K_E2_TEMP(7) & K_E2_TEMP(7) &
          K_E2_TEMP(7) & K_E2_TEMP(7) & K_E2_TEMP(7) & K_E2_TEMP(7) &
          K_E2_TEMP(7) & K_E2_TEMP(7) & K_E2_TEMP(7) & K_E2_TEMP(6 downto 0);

  K_E3 <= K_E3_TEMP(7) & K_E3_TEMP(7) & K_E3_TEMP(7) & K_E3_TEMP(7) &
          K_E3_TEMP(7) & K_E3_TEMP(7) & K_E3_TEMP(7) & K_E3_TEMP(7) &
          K_E3_TEMP(7) & K_E3_TEMP(7) & K_E3_TEMP(7) & K_E3_TEMP(6 downto 0);

  K_E4 <= K_E4_TEMP(7) & K_E4_TEMP(7) & K_E4_TEMP(7) & K_E4_TEMP(7) &
          K_E4_TEMP(7) & K_E4_TEMP(7) & K_E4_TEMP(7) & K_E4_TEMP(7) &
          K_E4_TEMP(7) & K_E4_TEMP(7) & K_E4_TEMP(7) & K_E4_TEMP(6 downto 0);

  K_E5 <= K_E5_TEMP(7) & K_E5_TEMP(7) & K_E5_TEMP(7) & K_E5_TEMP(7) &
          K_E5_TEMP(7) & K_E5_TEMP(7) & K_E5_TEMP(7) & K_E5_TEMP(7) &
          K_E5_TEMP(7) & K_E5_TEMP(7) & K_E5_TEMP(7) & K_E5_TEMP(6 downto 0);

  gCON3x3 : if (NOT Use_5x5_Convolution) generate

  iCONVOLVE3x3 : convolve
    generic map (
      N              => 8,
      LINE_LENGTH    => 384,
      KERNEL         => "GENERAL",
      RAM_ADDR_WIDTH => 9 )
    port map (
      DATA_IN    => DATA_C(7 downto 0),
      DATA_OUT   => DATA_CONV,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_CONV,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_CONV,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_CONV,
      K_A1       => K_B2,
      K_A2       => K_B3,
      K_A3       => K_B4,
      K_B1       => K_C2,
      K_B2       => K_C3,
      K_B3       => K_C4,
      K_C1       => K_D2,
      K_C2       => K_D3,
      K_C3       => K_D4,
      SHIFT      => SHIFT,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET );

  end generate;

  gCON5x5 : if (Use_5x5_Convolution) generate

  iCONVOLVE5x5 : convolve5x5
    generic map (
      N              => 8,
      LINE_LENGTH    => 384,
      RAM_ADDR_WIDTH => 9,
      KERNEL         => "GENERAL" )
    port map (
      DATA_IN    => DATA_C(7 downto 0),
      DATA_OUT   => DATA_CONV,
      DVALID_IN  => DVALID_C,
      DVALID_OUT => DVALID_CONV,
      EOL_IN     => EOL_C,
      EOL_OUT    => EOL_CONV,
      EOF_IN     => EOF_C,
      EOF_OUT    => EOF_CONV,
      K_A1       => K_A1,
      K_A2       => K_A2,
      K_A3       => K_A3,
      K_A4       => K_A4,
      K_A5       => K_A5,
      K_B1       => K_B1,
      K_B2       => K_B2,
      K_B3       => K_B3,
      K_B4       => K_B4,
      K_B5       => K_B5,
      K_C1       => K_C1,
      K_C2       => K_C2,
      K_C3       => K_C3,
      K_C4       => K_C4,
      K_C5       => K_C5,
      K_D1       => K_D1,
      K_D2       => K_D2,
      K_D3       => K_D3,
      K_D4       => K_D4,
      K_D5       => K_D5,
      K_E1       => K_E1,
      K_E2       => K_E2,
      K_E3       => K_E3,
      K_E4       => K_E4,
      K_E5       => K_E5,
      SHIFT      => SHIFT,
      CLOCK      => PIXEL_CLOCK,
      RESET      => RESET );

  end generate;

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

  process(IMAGE_BLOCK_SEL, DATA_C(7 downto 0), DATA_FILLK, DATA_SQU, DATA_MPYK, DATA_RSHK, DATA_LSHK, DATA_SUBK, DATA_XORK, DATA_XOR, DATA_SUB, DATA_NOT, DATA_AND, DATA_OR, DATA_ADD, DATA_CONV, DATA_ANDK, DATA_ADDK, DATA_ORK, DATA_RAMP)
  begin
    case(IMAGE_BLOCK_SEL)is
      when "00000000" => DATA_D(7 downto 0) <= DATA_C(7 downto 0);
      when "00000001" => DATA_D(7 downto 0) <= DATA_NOT;
      when "00000010" => DATA_D(7 downto 0) <= DATA_ANDK;
      when "00000011" => DATA_D(7 downto 0) <= DATA_SQU;
      when "00000100" => DATA_D(7 downto 0) <= DATA_MPYK;
      when "00000101" => DATA_D(7 downto 0) <= DATA_RSHK;
      when "00000110" => DATA_D(7 downto 0) <= DATA_LSHK;
      when "00000111" => DATA_D(7 downto 0) <= DATA_ADDK;
      when "00001000" => DATA_D(7 downto 0) <= DATA_ORK;
      when "00001001" => DATA_D(7 downto 0) <= DATA_XORK;
      when "00001010" => DATA_D(7 downto 0) <= DATA_SUBK;
      when "00001011" => DATA_D(7 downto 0) <= DATA_FILLK;
      when "00001100" => DATA_D(7 downto 0) <= DATA_RAMP;
--    when "00001101" => Reserved for loading SDRAM
      when "00001110" => DATA_D(7 downto 0) <= DATA_ADD;
      when "00001111" => DATA_D(7 downto 0) <= DATA_AND;
      when "00010000" => DATA_D(7 downto 0) <= DATA_OR;
      when "00010001" => DATA_D(7 downto 0) <= DATA_SUB;
      when "00010010" => DATA_D(7 downto 0) <= DATA_XOR;
      when "00010011" => DATA_D(7 downto 0) <= DATA_MPY;
      when "00010100" => DATA_D(7 downto 0) <= DATA_CONV;
      when others     => DATA_D(7 downto 0) <= DATA_C(7 downto 0);
    end case;
  end process;

  DATA_D(31 downto 8) <= (others=>'0');

  process(IMAGE_BLOCK_SEL, DVALID_C, DVALID_FILLK, DVALID_SQU, DVALID_MPYK, DVALID_RSHK, DVALID_LSHK, DVALID_SUBK, DVALID_XORK, DVALID_XOR, DVALID_SUB, DVALID_NOT, DVALID_AND, DVALID_OR, DVALID_ADD, DVALID_CONV, DVALID_ANDK, DVALID_ADDK, DVALID_ORK, DVALID_RAMP)
  begin
    case(IMAGE_BLOCK_SEL)is
      when "00000000" => DVALID_D <= DVALID_C;
      when "00000001" => DVALID_D <= DVALID_NOT;
      when "00000010" => DVALID_D <= DVALID_ANDK;
      when "00000011" => DVALID_D <= DVALID_SQU;
      when "00000100" => DVALID_D <= DVALID_MPYK;
      when "00000101" => DVALID_D <= DVALID_RSHK;
      when "00000110" => DVALID_D <= DVALID_LSHK;
      when "00000111" => DVALID_D <= DVALID_ADDK;
      when "00001000" => DVALID_D <= DVALID_ORK;
      when "00001001" => DVALID_D <= DVALID_XORK;
      when "00001010" => DVALID_D <= DVALID_SUBK;
      when "00001011" => DVALID_D <= DVALID_FILLK;
      when "00001100" => DVALID_D <= DVALID_RAMP;
--    when "00001101" => Reserved for loading SDRAM
      when "00001110" => DVALID_D <= DVALID_ADD;
      when "00001111" => DVALID_D <= DVALID_AND;
      when "00010000" => DVALID_D <= DVALID_OR;
      when "00010001" => DVALID_D <= DVALID_SUB;
      when "00010010" => DVALID_D <= DVALID_XOR;
      when "00010011" => DVALID_D <= DVALID_MPY;
      when "00010100" => DVALID_D <= DVALID_CONV;
      when others     => DVALID_D <= DVALID_C;
    end case;
  end process;

  process(IMAGE_BLOCK_SEL, EOL_C, EOL_FILLK, EOL_SQU, EOL_MPYK, EOL_RSHK, EOL_LSHK, EOL_SUBK, EOL_XORK, EOL_XOR, EOL_SUB, EOL_NOT, EOL_AND, EOL_OR, EOL_ADD, EOL_CONV, EOL_ANDK, EOL_ADDK, EOL_ORK, EOL_RAMP)
  begin
    case(IMAGE_BLOCK_SEL)is
      when "00000000" => EOL_D <= EOL_C;
      when "00000001" => EOL_D <= EOL_NOT;
      when "00000010" => EOL_D <= EOL_ANDK;
      when "00000011" => EOL_D <= EOL_SQU;
      when "00000100" => EOL_D <= EOL_MPYK;
      when "00000101" => EOL_D <= EOL_RSHK;
      when "00000110" => EOL_D <= EOL_LSHK;
      when "00000111" => EOL_D <= EOL_ADDK;
      when "00001000" => EOL_D <= EOL_ORK;
      when "00001001" => EOL_D <= EOL_XORK;
      when "00001010" => EOL_D <= EOL_SUBK;
      when "00001011" => EOL_D <= EOL_FILLK;
      when "00001100" => EOL_D <= EOL_RAMP;
--    when "00001101" => Reserved for loading SDRAM
      when "00001110" => EOL_D <= EOL_ADD;
      when "00001111" => EOL_D <= EOL_AND;
      when "00010000" => EOL_D <= EOL_OR;
      when "00010001" => EOL_D <= EOL_SUB;
      when "00010010" => EOL_D <= EOL_XOR;
      when "00010011" => EOL_D <= EOL_MPY;
      when "00010100" => EOL_D <= EOL_CONV;
      when others     => EOL_D <= EOL_C;
    end case;
  end process;

  process(IMAGE_BLOCK_SEL, EOF_C, EOF_FILLK, EOF_SQU, EOF_MPYK, EOF_RSHK, EOF_LSHK, EOF_SUBK, EOF_XORK, EOF_XOR, EOF_SUB, EOF_NOT, EOF_AND, EOF_OR, EOF_ADD, EOF_CONV, EOF_ANDK, EOF_ADDK, EOF_ORK, EOF_RAMP)
  begin
    case(IMAGE_BLOCK_SEL)is
      when "00000000" => EOF_D <= EOF_C;
      when "00000001" => EOF_D <= EOF_NOT;
      when "00000010" => EOF_D <= EOF_ANDK;
      when "00000011" => EOF_D <= EOF_SQU;
      when "00000100" => EOF_D <= EOF_MPYK;
      when "00000101" => EOF_D <= EOF_RSHK;
      when "00000110" => EOF_D <= EOF_LSHK;
      when "00000111" => EOF_D <= EOF_ADDK;
      when "00001000" => EOF_D <= EOF_ORK;
      when "00001001" => EOF_D <= EOF_XORK;
      when "00001010" => EOF_D <= EOF_SUBK;
      when "00001011" => EOF_D <= EOF_FILLK;
      when "00001100" => EOF_D <= EOF_RAMP;
--    when "00001101" => Reserved for loading SDRAM
      when "00001110" => EOF_D <= EOF_ADD;
      when "00001111" => EOF_D <= EOF_AND;
      when "00010000" => EOF_D <= EOF_OR;
      when "00010001" => EOF_D <= EOF_SUB;
      when "00010010" => EOF_D <= EOF_XOR;
      when "00010011" => EOF_D <= EOF_MPY;
      when "00010100" => EOF_D <= EOF_CONV;
      when others     => EOF_D <= EOF_C;
    end case;
  end process;

  iPACK_SYNC : PACK_SYNC
    port map (
      RESET       => RESET,
      PIXEL_CLOCK => PIXEL_CLOCK,
      M4_X_8      => '1',
      M2_X_16     => '0',
      M1_X_32     => '0',
      DVALID_IN   => DVALID_D,
      EOL_IN      => EOL_D,
      EOF_IN      => EOF_D,
      DATA_IN     => DATA_D,
      DVALID_OUT  => DVALID_E,
      DATA_OUT    => DATA_E );

  process(PIXEL_CLOCK, RESET)
  begin
    if RESET = '1' then
      Sync <= '1';   --Assume in sync initially
    elsif rising_edge(PIXEL_CLOCK) then
      if(DVALID_E = '1' and BUF_WR_FF = '1') then
        Sync <= '0';
      elsif (DVALID_E = '1' and DATA_E = "11111111111111111111111111111111") then
        Sync <= '1';
      end if;
    end if;
  end process;

  OUT_FIFOA_WR <= DVALID_E AND Sync;

  iFIFO511X32_A : fifo511x32
    port map (
      din          => DATA_E,
      wr_en        => OUT_FIFOA_WR,
      wr_clk       => PIXEL_CLOCK,
      rd_en        => OUT_FIFO_A_RD,
      rd_clk       => FCLK_G,
      ainit        => RESET,
      dout         => OUT_FIFO_A_DATA,
      full         => BUF_WR_FF,
      empty        => BUF_WR_EF,
      almost_full  => open,
      almost_empty => open,
      wr_count     => OUT_FIFO_COUNT,
      rd_count     => OUT_FIFO_RD_COUNT );

  OUT_FIFO_A_RD <= (NOT BUF_WR_EF) AND (NOT BUF_RD_AF);

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

  iFIFO2047X32 : fifo2047x32
    port map (
      din          => OUT_FIFO_A_DATA,
      wr_en        => OUT_FIFO_A_RD_DEL,
      wr_clk       => FCLK_G,
      rd_en        => RD_EN,
      rd_clk       => FCLK_G,
      ainit        => RESET,
      dout         => OUT_FIFO_DATA,
      full         => open,
      empty        => EMPTY,
      almost_full  => BUF_RD_AF,
      almost_empty => open );

  READY_A <= (OUTFIFO_READY(0) AND OUTFIFO_SEL(0)) OR
             (OUTFIFO_READY(1) AND OUTFIFO_SEL(1));

  READY_B <= (OUTFIFO_READY(2) AND OUTFIFO_SEL(2)) OR
             (OUTFIFO_READY(3) AND OUTFIFO_SEL(3));

  READY_C <= (OUTFIFO_READY(4) AND OUTFIFO_SEL(4)) OR
             (OUTFIFO_READY(5) AND OUTFIFO_SEL(5));

  RD_EN <= (READY_A OR READY_B OR READY_C) AND (NOT EMPTY);

  EMPTY_v <= EMPTY & EMPTY & EMPTY & EMPTY & EMPTY & EMPTY;

  WRITE <= (NOT EMPTY_v) AND OUTFIFO_READY AND OUTFIFO_SEL;

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

  OUTFIFO_D <= OUT_FIFO_DATA;

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

  iCAMLINK_HSB : CAMLINK_HSB
    port map(
      RESET           => RESET,
      CLOCK           => HSB_CLOCK,
      PIXEL_CLOCK     => PIXEL_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,
      M4_X_8          => open,
      M2_X_16         => open,
      M1_X_32         => open,
      BIT_SEL         => BIT_SEL,
      CP_SEL          => CP_SEL,
      CONTINUOUS      => CONTINUOUS,
      ODD_ONLY        => ODD_ONLY,
      LOAD            => LOAD,
      FRAMES          => FRAMES,
      AUTO_RES        => AUTO_RES,
      POLARITY        => POLARITY,
      USE_DVAL        => USE_DVAL,
      CAM_INPUTS      => CAM_INPUTS,
      START_PIXEL     => START_PIXEL,
      STOP_PIXEL      => STOP_PIXEL,
      START_LINE      => START_LINE,
      STOP_LINE       => STOP_LINE,
      OUTFIFO_SEL     => OUTFIFO_SEL,
      TX              => TX,
      RX              => RX,
      PIXEL_TOTAL     => PIXEL_TOTAL,
      LINE_TOTAL      => LINE_TOTAL,
      FIRST_PIXEL     => FIRST_PIXEL,
      LAST_PIXEL      => LAST_PIXEL,
      FIRST_LINE      => FIRST_LINE,
      LAST_LINE       => LAST_LINE,
      ACTIVE          => ACTIVE,
      ROI_VALID       => ROI_VALID,
      IMAGE_BLOCK_SEL => IMAGE_BLOCK_SEL,
      CAT1_CONST      => CAT1_CONST,
      EOF_A           => EOF_A,
      K_A1            => K_A1_TEMP,
      K_A2            => K_A2_TEMP,
      K_A3            => K_A3_TEMP,
      K_A4            => K_A4_TEMP,
      K_A5            => K_A5_TEMP,
      K_B1            => K_B1_TEMP,
      K_B2            => K_B2_TEMP,
      K_B3            => K_B3_TEMP,
      K_B4            => K_B4_TEMP,
      K_B5            => K_B5_TEMP,
      K_C1            => K_C1_TEMP,
      K_C2            => K_C2_TEMP,
      K_C3            => K_C3_TEMP,
      K_C4            => K_C4_TEMP,
      K_C5            => K_C5_TEMP,
      K_D1            => K_D1_TEMP,
      K_D2            => K_D2_TEMP,
      K_D3            => K_D3_TEMP,
      K_D4            => K_D4_TEMP,
      K_D5            => K_D5_TEMP,
      K_E1            => K_E1_TEMP,
      K_E2            => K_E2_TEMP,
      K_E3            => K_E3_TEMP,
      K_E4            => K_E4_TEMP,
      K_E5            => K_E5_TEMP,
      SHIFT           => SHIFT );

  CAM_SER_TC   <= TX;

  RX <= CAM_SER_TFG;

end RTL;
