-------------------------------------------------------------------------------
--
-- Project name: JESD204b Receiver core 
--
-- (C) Copyright 2017 DFC Design, s.r.o., Brno, Czech Republic
-- Author: Marek Kvas (m.kvas@dfcdesign.cz)
--
-------------------------------------------------------------------------------
--
-- This is AXI4-Lite wrapper for JESD204B core. It enables access to all 
-- configuration, control, status and monitoring registers via AXI.
--
-- CLK is main clock that controls data path. It is usually output of
-- PHY core. All ports accept AXI are sampled on this clock.
--
-- AXI interface has its own independent clock that should never stop.
--
-------------------------------------------------------------------------------


library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity jesd204b_rx_axi is 
   generic (
      g_lane_count         : integer range 1 to 16 := 2;
      g_stat_cnt_length    : integer := 16;
      g_scrambler_incl     : boolean := true;
      g_lmfc_buffer_size   : integer := 1024;

      g_axi_timeout        : integer := 10;
      C_S_AXI_DATA_WIDTH   : integer := 32;
      C_S_AXI_ADDR_WIDTH   : integer := 14
           );
   port (
      CLK                  : in  std_logic;
   
      -- JESD204B control signals
      SYNC                 : out std_logic;
      SYSREF               : in  std_logic;

      -- Connection to PHY (RX transceivers)
      PHY_DATA             : in  std_logic_vector(g_lane_count * 32 -1 downto 0);
      PHY_CHARISK          : in  std_logic_vector(g_lane_count * 4 - 1 downto 0);
      PHY_DISPERR          : in  std_logic_vector(g_lane_count * 4 - 1 downto 0);
      PHY_NOTINTABLE       : in  std_logic_vector(g_lane_count * 4 - 1 downto 0);
      PHY_COMMA_ALIGN_EN   : out std_logic_vector(g_lane_count - 1 downto 0);
      
      -- Output AXI4-Stream integrface
      OUT_M_AXIS_TVALID    : out std_logic;
      OUT_M_AXIS_TDATA     : out std_logic_vector(g_lane_count * 32 -1 downto 0);
      OUT_SOF              : out std_logic_vector(3 downto 0);
      OUT_EOF              : out std_logic_vector(3 downto 0);
      OUT_SOMF             : out std_logic_vector(3 downto 0);
      OUT_EOMF             : out std_logic_vector(3 downto 0);
      OUT_BYTE_ERR         : out std_logic_vector(g_lane_count * 4 - 1 downto 0);

      -- AXI Lite slave interface for control purposes
      -- AXI Lite bus Slave interface
      S_AXI_ACLK        : in  std_logic;
      S_AXI_ARESETN     : in  std_logic;
      S_AXI_AWADDR      : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
      S_AXI_AWPROT      : in  std_logic_vector(2 downto 0);
      S_AXI_AWVALID     : in  std_logic;
      S_AXI_AWREADY     : out std_logic;
      S_AXI_WDATA       : in  std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
      S_AXI_WSTRB       : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
      S_AXI_WVALID      : in  std_logic;
      S_AXI_WREADY      : out std_logic;
      S_AXI_BRESP       : out std_logic_vector(1 downto 0);
      S_AXI_BVALID      : out std_logic;
      S_AXI_BREADY      : in  std_logic;
      S_AXI_ARADDR      : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
      S_AXI_ARPROT      : in  std_logic_vector(2 downto 0);
      S_AXI_ARVALID     : in  std_logic;
      S_AXI_ARREADY     : out std_logic;
      S_AXI_RDATA       : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
      S_AXI_RRESP       : out std_logic_vector(1 downto 0);
      S_AXI_RVALID      : out std_logic;
      S_AXI_RREADY      : in  std_logic
        );
end entity;


architecture synthesis of jesd204b_rx_axi is

   constant LC_MAGIC_REVISION_REG   : std_logic_vector(31 downto 0) := 
                                       x"DFC00009";

   signal r_ctrl_srst_wr             : std_logic;
   signal r_ctrl_monrst_wr           : std_logic;
   signal r_cfg_f_rw                 : std_logic_vector(7 downto 0);
   signal r_cfg_k_rw                 : std_logic_vector(4 downto 0);
   signal r_cfg_fxk_rw               : std_logic_vector(10 downto 0);
   signal r_cfg_subclass_rw          : std_logic_vector(1 downto 0);
   signal r_cfg_err_report_en_rw     : std_logic;
   signal r_cfg_reinit_en_rw         : std_logic;
   signal r_cfg_ilas_rw              : std_logic;
   signal r_cfg_scrambling_en_rw     : std_logic;
   signal r_cfg_sysref_delay_rw      : std_logic_vector(3 downto 0);
   signal r_cfg_sysref_allresync_rw  : std_logic;
   signal r_cfg_sysref_polarity_rw   : std_logic;
   signal r_lane_ilas_cfg_done_ro    : std_logic_vector(g_lane_count-1 downto 0);
   signal r_lane_ilas_cfg_data_ro    : std_logic_vector(
                                                   g_lane_count*16*8-1 downto 0);
   signal r_status_sysref_seen_ro    : std_logic;
   signal r_status_sync_ok_ro        : std_logic;
   signal r_status_sync_err_ro       : std_logic;
   signal r_status_sync_err_diff_ro  : std_logic_vector(10 downto 0);
   signal r_sw_glob_rst_wr           : std_logic;
   signal r_lane_status_ro           : std_logic_vector(g_lane_count * 8 - 1
                                                                downto 0);
   signal r_lane_mon_phys_err_cnt_ro       : std_logic_vector(
                         g_lane_count * g_stat_cnt_length - 1 downto 0);
   signal r_lane_mon_phys_err_res_cnt_ro   : std_logic_vector(
                         g_lane_count * g_stat_cnt_length - 1 downto 0);
   signal r_lane_mon_align_f_err_cnt_ro    : std_logic_vector(
                         g_lane_count * g_stat_cnt_length - 1 downto 0);
   signal r_lane_mon_align_mf_err_cnt_ro   : std_logic_vector(
                         g_lane_count * g_stat_cnt_length - 1 downto 0);
   signal r_lane_mon_replace_f_cnt_ro      : std_logic_vector(
                         g_lane_count * g_stat_cnt_length - 1 downto 0);
   signal r_lane_mon_replace_a_cnt_ro      : std_logic_vector(
                         g_lane_count * g_stat_cnt_length - 1 downto 0);
   signal r_lane_mon_unknown_k_cnt_ro      : std_logic_vector(
                         g_lane_count * g_stat_cnt_length - 1 downto 0);
   signal r_lane_mon_ilas_err_cnt_ro       : std_logic_vector(
                        g_lane_count * g_stat_cnt_length - 1 downto 0);
   signal glob_rst                     : std_logic;



begin

   jesd204b_axi_reg_inst : entity work.jesd204b_axi_reg
   generic map (
      g_magic_revision_reg => LC_MAGIC_REVISION_REG,

      g_stat_cnt_length    => g_stat_cnt_length,
      g_lane_count         => g_lane_count,

      g_axi_timeout        => g_axi_timeout,
      C_S_AXI_DATA_WIDTH   => C_S_AXI_DATA_WIDTH,
      C_S_AXI_ADDR_WIDTH   => C_S_AXI_ADDR_WIDTH
           )
   port map (
      SYS_CLK                 => CLK,
      SYS_RST                 => glob_rst,

      ------
      -- Registers in system domain
      -- Common to all lanes
      R_CTRL_SRST_WR             => r_ctrl_srst_wr,
      R_CTRL_MONRST_WR           => r_ctrl_monrst_wr,
      
      R_CFG_F_RW                 => r_cfg_f_rw,
      R_CFG_K_RW                 => r_cfg_k_rw,
      R_CFG_FxK_RW               => r_cfg_fxk_rw,
      R_CFG_SUBCLASS_RW          => r_cfg_subclass_rw,
      R_CFG_ERR_REPORT_EN_RW     => r_cfg_err_report_en_rw,
      R_CFG_REINIT_EN_RW         => r_cfg_reinit_en_rw,
      R_CFG_ILAS_RW              => r_cfg_ilas_rw,
      R_CFG_SCRAMBLING_EN_RW     => r_cfg_scrambling_en_rw,

      R_CFG_SYSREF_DELAY_RW      => r_cfg_sysref_delay_rw,
      R_CFG_SYSREF_ALLRESYNC_RW  => r_cfg_sysref_allresync_rw,
      R_CFG_SYSREF_POLARITY_RW   => r_cfg_sysref_polarity_rw,

      R_STATUS_SYSREF_SEEN_RO    => r_status_sysref_seen_ro,
      R_STATUS_SYNC_OK_RO        => r_status_sync_ok_ro,

      R_STATUS_SYNC_ERR_RO       => r_status_sync_err_ro,
      R_STATUS_SYNC_ERR_DIFF_RO  => r_status_sync_err_diff_ro,

      -- Specific to each lane
      R_LANE_ILAS_CFG_DONE_RO    => r_lane_ilas_cfg_done_ro,
      R_LANE_ILAS_CFG_DATA_RO    => r_lane_ilas_cfg_data_ro,
      R_LANE_STATUS_RO           => r_lane_status_ro,
      R_LANE_MON_PHYS_ERR_CNT_RO       => r_lane_mon_phys_err_cnt_ro,
      R_LANE_MON_PHYS_ERR_RES_CNT_RO   => r_lane_mon_phys_err_res_cnt_ro,
      R_LANE_MON_ALIGN_F_ERR_CNT_RO    => r_lane_mon_align_f_err_cnt_ro,
      R_LANE_MON_ALIGN_MF_ERR_CNT_RO   => r_lane_mon_align_mf_err_cnt_ro,
      R_LANE_MON_REPLACE_F_CNT_RO      => r_lane_mon_replace_f_cnt_ro,
      R_LANE_MON_REPLACE_A_CNT_RO      => r_lane_mon_replace_a_cnt_ro,
      R_LANE_MON_UNKNOWN_K_CNT_RO      => r_lane_mon_unknown_k_cnt_ro,
      R_LANE_MON_ILAS_ERR_CNT_RO       => r_lane_mon_ilas_err_cnt_ro,

      ------
      -- Registers in AXI clock domain
      R_SW_GLOB_RST_WR  => r_sw_glob_rst_wr,


      -- AXI Lite slave interface for control purposes
      -- AXI Lite bus Slave interface
      S_AXI_ACLK        => S_AXI_ACLK,
      S_AXI_ARESETN     => S_AXI_ARESETN,
      S_AXI_AWADDR      => S_AXI_AWADDR,
      S_AXI_AWPROT      => S_AXI_AWPROT,
      S_AXI_AWVALID     => S_AXI_AWVALID,
      S_AXI_AWREADY     => S_AXI_AWREADY,
      S_AXI_WDATA       => S_AXI_WDATA,
      S_AXI_WSTRB       => S_AXI_WSTRB,
      S_AXI_WVALID      => S_AXI_WVALID,
      S_AXI_WREADY      => S_AXI_WREADY,
      S_AXI_BRESP       => S_AXI_BRESP,
      S_AXI_BVALID      => S_AXI_BVALID,
      S_AXI_BREADY      => S_AXI_BREADY,
      S_AXI_ARADDR      => S_AXI_ARADDR,
      S_AXI_ARPROT      => S_AXI_ARPROT,
      S_AXI_ARVALID     => S_AXI_ARVALID,
      S_AXI_ARREADY     => S_AXI_ARREADY,
      S_AXI_RDATA       => S_AXI_RDATA,
      S_AXI_RRESP       => S_AXI_RRESP,
      S_AXI_RVALID      => S_AXI_RVALID,
      S_AXI_RREADY      => S_AXI_RREADY
        );
   -- Synchronize gobal reset from AXI domain
   glob_rst_xcdc_inst : entity work.xcdc
   port map (CLK, r_sw_glob_rst_wr, glob_rst);



   jesd204b_rx_inst : entity work.jesd204b_rx 
   generic map (
      g_lane_count         => g_lane_count,
      g_stat_cnt_length    => g_stat_cnt_length,
      g_scrambler_incl     => g_scrambler_incl,
      g_lmfc_buffer_size   => g_lmfc_buffer_size
           )
   port map (
      CLK                  => CLK,
      RST                  => r_ctrl_srst_wr,
   
      -- JESD204B control signals
      SYNC                 => SYNC,
      SYSREF               => SYSREF,

      -- Connection to PHY (RX transceivers)
      PHY_DATA             => PHY_DATA,
      PHY_CHARISK          => PHY_CHARISK,
      PHY_DISPERR          => PHY_DISPERR,
      PHY_NOTINTABLE       => PHY_NOTINTABLE,
      PHY_COMMA_ALIGN_EN   => PHY_COMMA_ALIGN_EN,
      
      -- Output AXI4-Stream integrface
      OUT_M_AXIS_TVALID    => OUT_M_AXIS_TVALID,
      OUT_M_AXIS_TDATA     => OUT_M_AXIS_TDATA,
      OUT_SOF              => OUT_SOF,
      OUT_EOF              => OUT_EOF,
      OUT_SOMF             => OUT_SOMF,
      OUT_EOMF             => OUT_EOMF,
      OUT_BYTE_ERR         => OUT_BYTE_ERR,
      OUT_ILAS_CFG_DATA    => r_lane_ilas_cfg_data_ro,
      OUT_ILAS_CFG_DONE    => r_lane_ilas_cfg_done_ro,
      
      
      CFG_F                => r_cfg_f_rw,
      CFG_K                => r_cfg_k_rw,
      CFG_FxK              => r_cfg_fxk_rw,
      CFG_SUBCLASS         => r_cfg_subclass_rw,
      CFG_ERR_REPORT_EN    => r_cfg_err_report_en_rw,
      CFG_REINIT_EN        => r_cfg_reinit_en_rw,
      CFG_ILAS             => r_cfg_ilas_rw,
      CFG_SCRAMBLING_EN    => r_cfg_scrambling_en_rw,
      CFG_SYSREF_DELAY     => r_cfg_sysref_delay_rw,
      CFG_SYSREF_ALLRESYNC => r_cfg_sysref_allresync_rw,
      CFG_SYSREF_POLARITY  => r_cfg_sysref_polarity_rw,
   
      STAT_SYSREF_SEEN     => r_status_sysref_seen_ro,
      STAT_SYNC_OK         => r_status_sync_ok_ro,
      STAT_ERR_LMFC_SYNC   => r_status_sync_err_ro,
      STAT_ERR_LMFC_DIFF   => r_status_sync_err_diff_ro,
      
      LANE_STATUS          => r_lane_status_ro,
      MON_RST              => r_ctrl_monrst_wr,
      LANE_MON_PHYS_ERR_CNT       => r_lane_mon_phys_err_cnt_ro,
      LANE_MON_PHYS_ERR_RES_CNT   => r_lane_mon_phys_err_res_cnt_ro,
      LANE_MON_ALIGN_F_ERR_CNT    => r_lane_mon_align_f_err_cnt_ro,
      LANE_MON_ALIGN_MF_ERR_CNT   => r_lane_mon_align_mf_err_cnt_ro,
      LANE_MON_REPLACE_F_CNT      => r_lane_mon_replace_f_cnt_ro,
      LANE_MON_REPLACE_A_CNT      => r_lane_mon_replace_a_cnt_ro,
      LANE_MON_UNKNOWN_K_CNT      => r_lane_mon_unknown_k_cnt_ro,
      LANE_MON_ILAS_ERR_CNT       => r_lane_mon_ilas_err_cnt_ro
      
        );




end architecture;
