--_________________________________________________________________________________________________
--                                                                                                |
--                                         |The nanoFIP|                                          |
--                                                                                                |
--                                         CERN,BE/CO-HT                                          |
--________________________________________________________________________________________________|

---------------------------------------------------------------------------------------------------
--                                                                                                |
--                                         masterFIP_pkg                                          |
--                                                                                                |
---------------------------------------------------------------------------------------------------
-- File         masterFIP_pkg.vhd                                                                 |
--                                                                                                |
-- Description  Definitions of constants, types, entities, functions                              |
-- Author       Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)                             |
--              Evangelia Gousiou     (Evangelia.Gousiou@cern.ch)                                 |
-- Date         11/01/2011                                                                        |
-- Version      v0.05                                                                             |
----------------                                                                                  |
-- Last changes                                                                                   |
--      8/2010  v0.01  EG  byte_array of all vars cleaned_up (ex: subs_i removed)                 |
--     10/2010  v0.02  EG  base_addr unsigned(8 downto 0) instead of                              |
--                         std_logic_vector (9 downto 0) to simplify calculations; cleaning-up    |
--      1/2011  v0.03  EG  turnaround times & broadcast var (91h) updated following new specs     |
--                         added DualClkRam                                                       |
--      2/2011  v0.04  EG  function for manch_encoder; cleaning up of constants+generics          |
--                         added CTRL bytes for RP_DAT_MSG and RP_DAT_RQ and RP_DAT_RQ_MSG        |
--      2/2011  v0.05  EG  JTAG variables added                                                   |
--     11/2011  v0.06  EG  c_SESSION_TIMEOUT_C_LGTH, c_JTAG_TIMEOUT_C_LGTH added                  |
---------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------
--                               GNU LESSER GENERAL PUBLIC LICENSE                                |
--                              ------------------------------------                              |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either     |
-- version 2.1 of the License, or (at your option) any later version.                             |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;       |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.      |
-- See the GNU Lesser General Public License for more details.                                    |
-- You should have received a copy of the GNU Lesser General Public License along with this       |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html                     |
---------------------------------------------------------------------------------------------------



--=================================================================================================
--                                      Libraries & Packages
--=================================================================================================

-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all;    -- conversion functions
use work.wishbone_pkg.all;
use work.gencores_pkg.all;



--=================================================================================================
--                              Package declaration for masterFIP_pkg
--=================================================================================================
package masterFIP_pkg is


---------------------------------------------------------------------------------------------------
--                        Constants regarding the SDB Devices Definitions                        --
---------------------------------------------------------------------------------------------------
-- Note: All address in sdb and crossbar are BYTE addresses!

  -- Devices sdb description
  constant c_ONEWIRE_SDB_DEVICE : t_sdb_device :=
    (abi_class     => x"0000",               -- undocumented device
     abi_ver_major => x"01",
     abi_ver_minor => x"01",
     wbd_endian    => c_sdb_endian_big,
     wbd_width     => x"4",                  -- 32-bit port granularity
     sdb_component =>
       (addr_first  => x"0000000000000000",
        addr_last   => x"0000000000000007",
        product     =>
          (vendor_id => x"000000000000CE42", -- CERN
           device_id => x"00000602",         -- "WB-Onewire.Control " | md5sum | cut -c1-8
           version   => x"00000001",
           date      => x"20121116",
           name      => "WB-Onewire.Control ")));

  constant c_SPEC_INFO_SDB_DEVICE : t_sdb_device :=
    (abi_class     => x"0000",               -- undocumented device
     abi_ver_major => x"01",
     abi_ver_minor => x"01",
     wbd_endian    => c_sdb_endian_big,
     wbd_width     => x"4",                  -- 32-bit port granularity
     sdb_component =>
       (addr_first  => x"0000000000000000",
        addr_last   => x"000000000000001F",
        product     =>
          (vendor_id => x"000000000000CE42", -- CERN
           device_id => x"00000603",         -- "WB-SPEC.CSR        " | md5sum | cut -c1-8
           version   => x"00000001",
           date      => x"20121116",
           name      => "WB-SPEC.CSR        ")));

  constant c_MASTERFIP_EIC_SDB_DEVICE : t_sdb_device :=
    (abi_class     => x"0000",               -- undocumented device
     abi_ver_major => x"01",
     abi_ver_minor => x"01",
     wbd_endian    => c_sdb_endian_big,
     wbd_width     => x"4",                  -- 32-bit port granularity
     sdb_component =>
       (addr_first  => x"0000000000000000",
        addr_last   => x"000000000000000F",
        product     =>
          (vendor_id => x"000000000000CE42", -- CERN
           device_id => x"00000605",         -- "WB-FMC-ADC.EIC     " | md5sum | cut -c1-8
           version   => x"00000001",
           date      => x"20121116",
           name      => "WB-MASTERFIP.EIC   ")));


  constant c_I2C_SDB_DEVICE : t_sdb_device :=
    (abi_class     => x"0000",               -- undocumented device
     abi_ver_major => x"01",
     abi_ver_minor => x"01",
     wbd_endian    => c_sdb_endian_big,
     wbd_width     => x"4",                  -- 32-bit port granularity
     sdb_component =>
       (addr_first  => x"0000000000000000",
        addr_last   => x"000000000000001F",
        product     =>
          (vendor_id => x"000000000000CE42", -- CERN
           device_id => x"00000606",         -- "WB-I2C.Control     " | md5sum | cut -c1-8
           version   => x"00000001",
           date      => x"20121116",
           name      => "WB-I2C.Control     ")));

  constant c_MASTERFIP_CSR_SDB_DEVICE : t_sdb_device :=
    (abi_class     => x"0000",               -- undocumented device
     abi_ver_major => x"01",
     abi_ver_minor => x"01",
     wbd_endian    => c_sdb_endian_big,
     wbd_width     => x"4",                  -- 32-bit port granularity
     sdb_component =>
       (addr_first  => x"0000000000000000",
        addr_last   => x"00000000000000FF",
        product     =>
          (vendor_id => x"000000000000CE42", -- CERN
           device_id => x"00000604",         -- "WB-TDC-Core-Config " | md5sum | cut -c1-8
           version   => x"00000001",
           date      => x"20130429",
           name      => "WB-MASTERFIP.CSR   ")));


---------------------------------------------------------------------------------------------------
--                               Constant regarding the user clock                               --
---------------------------------------------------------------------------------------------------

  constant c_QUARTZ_PERIOD : real := 25.0;

---------------------------------------------------------------------------------------------------
--                                Vector with the data Registers                                 --
---------------------------------------------------------------------------------------------------
  subtype data_word is std_logic_vector(31 downto 0);
  type rx_frame_t   is array (31 downto 0) of data_word;
  type tx_frame_t   is array (31 downto 0) of data_word;


---------------------------------------------------------------------------------------------------
--                 Constants regarding addressing of the configuration registers                 --
---------------------------------------------------------------------------------------------------


---------------------------------------------------------------------------------------------------
--                       Constants regarding the session timeout counters                        --
---------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------
-- To add a robust layer of protection to the FSMs of the design, counters that depend only on
-- the system clock have being implemented; when they are filled up, they can bring the FSMs back
-- to the IDLE state.

-- For the wf_rx_deserializer, at the slowest bit rate, 31.25 kbps, the reception of the longest
-- frame should not last more than:
-- 133 bytes RP_DAT = 34048 us
-- This demands for a 21 bits counter.

-- Similarly, for the wf_tx_serializer, at the slowest bit rate, 31.25 kbps, the transmission of
-- the longest frame should not last more than:
-- 133 bytes RP_DAT = 34048 us
-- This demands for a 21 bits counter.

-- For the wf_engine_control, at the slowest bit rate, 31.25 kbps, the reception of an ID_DAT frame
-- followed by the reception/ transmission of an RP_DAT should not last more than:
-- 8 bytes ID_DAT   = 2048  us
-- silence time     = 4096  us
-- 133 bytes RP_DAT = 34048 us
--                  ------------
--                    40192 us
-- This also demands for a 21 bits counter.

-- Therefore the same length of the timeout counters can be used for the FSMs of the wf_rx_deserializer,
-- wf_tx_serializer and wf_engine_control. The FSMs will be reset if 52 ms (complete 21 bit counter)
-- have passed since they have left the IDLE state.

  constant c_SESSION_TIMEOUT_C_LGTH : natural := 21;


---------------------------------------------------------------------------------------------------
--                             Constant regarding the deglitch filter                            --
---------------------------------------------------------------------------------------------------

  constant c_DEGLITCH_THRESHOLD : natural := 4;


---------------------------------------------------------------------------------------------------
--                            Constant regarding the frame structure                             --
---------------------------------------------------------------------------------------------------

  constant c_MAX_FRAME_BYTES : natural := 130; -- maximum number of bytes in a frame after the
                                               -- FSS (counting starts from 0!)


---------------------------------------------------------------------------------------------------
--                            Constants regarding the CRC calculation                            --
---------------------------------------------------------------------------------------------------
  constant c_CRC_POLY_LGTH  : natural                                         := 16;
  constant c_CRC_GENER_POLY : std_logic_vector (c_CRC_POLY_LGTH - 1 downto 0) := "0001110111001111";
  constant c_CRC_VERIF_POLY : std_logic_vector (c_CRC_POLY_LGTH - 1 downto 0) := "0001110001101011";


---------------------------------------------------------------------------------------------------
--                     Constants regarding the the ID_DAT and RP_DAT frame structure             --
---------------------------------------------------------------------------------------------------

  constant c_VP   : std_logic_vector (1 downto 0) := "11";
  constant c_VN   : std_logic_vector (1 downto 0) := "00";
  constant c_ONE  : std_logic_vector (1 downto 0) := "10";
  constant c_ZERO : std_logic_vector (1 downto 0) := "01";

  constant c_PRE  : std_logic_vector (15 downto 0) := c_ONE & c_ZERO & c_ONE & c_ZERO & c_ONE & c_ZERO & c_ONE & c_ZERO;
  constant c_FSD  : std_logic_vector (15 downto 0) := c_ONE & c_VP & c_VN & c_ONE & c_ZERO & c_VN & c_VP & c_ZERO;
  constant c_FES  : std_logic_vector (15 downto 0) := c_ONE & c_VP & c_VN & c_VP & c_VN & c_ONE & c_ZERO & c_ONE;
  constant c_FSS  : std_logic_vector (31 downto 0) := c_PRE & c_FSD;

---------------------------------------------------------------------------------------------------
--                               Constant regarding the Transmitter                              --
---------------------------------------------------------------------------------------------------

  constant c_TX_SCHED_BUFF_LGTH : natural := 4; -- length of the buffer of pulses used for
                                                -- the transmission synchronization

---------------------------------------------------------------------------------------------------
--                 Constants regarding the position of bytes in the frame structure              --
---------------------------------------------------------------------------------------------------

  constant c_CTRL_BYTE_INDEX     : std_logic_vector (7 downto 0) := "00000000"; -- 0
  constant c_SUBS_BYTE_INDEX     : std_logic_vector (7 downto 0) := "00000010"; -- 2

  constant c_PDU_BYTE_INDEX      : std_logic_vector (7 downto 0) := "00000001"; -- 1
  constant c_LGTH_BYTE_INDEX     : std_logic_vector (7 downto 0) := "00000010"; -- 2
  constant c_1st_DATA_BYTE_INDEX : std_logic_vector (7 downto 0) := "00000011"; -- 3


---------------------------------------------------------------------------------------------------
--                           Constants & Types regarding the bit rate                            --
---------------------------------------------------------------------------------------------------

  -- Calculation of the number of uclk ticks equivalent to the reception/ transmission period

  constant c_PERIODS_COUNTER_LGTH : natural := 11; -- in the slowest bit rate (31.25kbps), the
                                                   -- period is 32000 ns and can be measured after
                                                   -- 1280 uclk ticks. Therefore a counter of 11
                                                   -- bits is the max needed for counting
                                                   -- transmission/ reception periods.

  constant c_BIT_RATE_UCLK_TICKS_31_25Kbit: unsigned :=
                          to_unsigned((32000 / integer(C_QUARTZ_PERIOD)),c_PERIODS_COUNTER_LGTH);
  constant c_BIT_RATE_UCLK_TICKS_1_Mbit: unsigned    :=
                          to_unsigned((1000 / integer(C_QUARTZ_PERIOD)),c_PERIODS_COUNTER_LGTH);
  constant c_BIT_RATE_UCLK_TICKS_2_5_Mbit: unsigned  :=
                          to_unsigned((400 /integer(C_QUARTZ_PERIOD)),c_PERIODS_COUNTER_LGTH);

  -- Creation of a table with the c_BIT_RATE_UCLK_TICKS info per bit rate
  type t_uclk_ticks is array (Natural range <>) of unsigned (c_PERIODS_COUNTER_LGTH-1 downto 0);

  constant c_BIT_RATE_UCLK_TICKS : t_uclk_ticks (3 downto 0):=
                          (0 => (c_BIT_RATE_UCLK_TICKS_31_25Kbit),
                           1 => (c_BIT_RATE_UCLK_TICKS_1_Mbit),
                           2 => (c_BIT_RATE_UCLK_TICKS_2_5_Mbit),
                           3 => (c_BIT_RATE_UCLK_TICKS_2_5_Mbit));

  constant c_2_PERIODS_COUNTER_LGTH : natural := 12; -- length of a counter counting 2 reception/
                                                     -- transmission periods

---------------------------------------------------------------------------------------------------
--                     Constants & Types regarding the turnaround and silence times              --
---------------------------------------------------------------------------------------------------

  -- Construction of a table with the turnaround and silence times for each bit rate.
  -- The table contains the number of uclk ticks corresponding to the turnaround/ silence times.

  type t_timeouts is
  record
    turnaround : integer;
    silence    : integer;
  end record;

  constant c_31K25_INDEX   : integer := 0;
  constant c_1M_INDEX      : integer := 1;
  constant c_2M5_INDEX     : integer := 2;
  constant c_RESERVE_INDEX : integer := 3;

  type t_timeouts_table is array (natural range <>) of t_timeouts;

  constant c_TIMEOUTS_TABLE : t_timeouts_table(3 downto 0) :=

                              (c_31K25_INDEX   => (turnaround => integer (480000.0  / c_QUARTZ_PERIOD),
                                                   silence    => integer (4096000.0 / c_QUARTZ_PERIOD)),

                               c_1M_INDEX      => (turnaround => integer (14000.0   / c_QUARTZ_PERIOD),
                                                   silence    => integer (150000.0  / c_QUARTZ_PERIOD)),

                               c_2M5_INDEX     => (turnaround => integer (13500.0   / c_QUARTZ_PERIOD),
                                                   silence    => integer (96000.0 / c_QUARTZ_PERIOD)),

                               c_RESERVE_INDEX => (turnaround => integer (480000.0  /C_QUARTZ_PERIOD),
                                                   silence    => integer (4096000.0 /C_QUARTZ_PERIOD)));

---------------------------------------------------------------------------------------------------
--                           Constants regarding the One-Wire interface                          --
---------------------------------------------------------------------------------------------------
  constant c_FMC_ONEWIRE_NB   : integer := 1;


---------------------------------------------------------------------------------------------------
--                            Constants regarding the Carrier CSR info                           --
---------------------------------------------------------------------------------------------------
  constant c_CARRIER_TYPE   : std_logic_vector(15 downto 0) := X"0001";



---------------------------------------------------------------------------------------------------
--                                      Components Declarations:                                 --
---------------------------------------------------------------------------------------------------


  component fmc_masterFIP_mezzanine is
  generic
    (g_with_wrabbit_core: boolean := FALSE;
     g_span             : integer := 32;
     g_width            : integer := 32;
     values_for_simul   : boolean := FALSE);
  port
    (clk_sys_i          : in    std_logic;
     rst_sys_n_i        : in    std_logic;
     fd_rxcdn_i         : in    std_logic;
     fd_rxd_i           : in    std_logic;
     fd_txer_i          : in    std_logic;
     fd_wdgn_i          : in    std_logic;
     fd_rstn_o          : out   std_logic;
     fd_txck_o          : out   std_logic;
     fd_txd_o           : out   std_logic;
     fd_txena_o         : out   std_logic;
     wb_adr_i           : in    std_logic_vector(31 downto 0);
     wb_dat_i           : in    std_logic_vector(31 downto 0);
     wb_cyc_i           : in    std_logic;
     wb_sel_i           : in    std_logic_vector(3 downto 0);
     wb_stb_i           : in    std_logic;
     wb_we_i            : in    std_logic;
     wb_dat_o           : out   std_logic_vector(31 downto 0);
     wb_ack_o           : out   std_logic;
     wb_stall_o         : out   std_logic;
     wb_irq_o           : out   std_logic;
     i2c_scl_o          : out   std_logic;
     i2c_scl_oen_o      : out   std_logic;
     i2c_scl_i          : in    std_logic;
     i2c_sda_oen_o      : out   std_logic;
     i2c_sda_o          : out   std_logic;
     i2c_sda_i          : in    std_logic;
     onewire_b          : inout std_logic;
     aux_o              : out   std_logic_vector(7 downto 0));

     end component;


  
  component fmc_masterfip_csr is
  port (
    rst_n_i                                  : in     std_logic;
    clk_sys_i                                : in     std_logic;
    wb_adr_i                                 : in     std_logic_vector(6 downto 0);
    wb_dat_i                                 : in     std_logic_vector(31 downto 0);
    wb_dat_o                                 : out    std_logic_vector(31 downto 0);
    wb_cyc_i                                 : in     std_logic;
    wb_sel_i                                 : in     std_logic_vector(3 downto 0);
    wb_stb_i                                 : in     std_logic;
    wb_we_i                                  : in     std_logic;
    wb_ack_o                                 : out    std_logic;
    wb_stall_o                               : out    std_logic;
    mf_rst_core_o                            : out    std_logic;
    mf_rst_fd_o                              : out    std_logic;
    mf_rst_lock_o                            : out    std_logic_vector(15 downto 0);
    mf_rst_lock_wr_o                         : out    std_logic;
    mf_config_host_bitrate_o                 : out    std_logic_vector(1 downto 0);
    mf_config_host_ext_sync_term_en_n_o      : out    std_logic;
    mf_config_host_subs_o                    : out    std_logic_vector(7 downto 0);
    mf_config_fmc_bitrate_i                  : in     std_logic_vector(1 downto 0);
    mf_config_fmc_bitrate_ok_i               : in     std_logic;
    mf_macrocyc_lgth_o                       : out    std_logic_vector(31 downto 0);
    mf_turnar_lgth_o                         : out    std_logic_vector(31 downto 0);
    mf_silen_lgth_o                          : out    std_logic_vector(31 downto 0);
    mf_macrocyc_time_cnt_i                   : in     std_logic_vector(31 downto 0);
    mf_turnar_time_cnt_i                     : in     std_logic_vector(31 downto 0);
    mf_silen_time_cnt_i                      : in     std_logic_vector(31 downto 0);
    mf_ext_sync_tstamp_i                     : in     std_logic_vector(31 downto 0);
    mf_tx_rst_o                              : out    std_logic;
    mf_tx_start_o                            : out    std_logic;
    mf_tx_bytes_num_o                        : out    std_logic_vector(8 downto 0);
    mf_tx_stop_i                             : in     std_logic;
    mf_fd_wdgn_i                             : in     std_logic;
    mf_fd_txer_i                             : in     std_logic;
    mf_rx_rst_o                              : out    std_logic;
    mf_rx_pream_ok_i                         : in     std_logic;
    mf_rx_frame_ok_i                         : in     std_logic;
    mf_rx_frame_err_i                        : in     std_logic;
    mf_rx_frame_err_code_i                   : in     std_logic_vector(2 downto 0);
    mf_rx_bytes_num_i                        : in     std_logic_vector(8 downto 0);
    mf_rx_data_ctrl_i                        : in     std_logic_vector(7 downto 0);
    mf_rx_data_reg1_i                        : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg2_i                        : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg3_i                        : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg4_i                        : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg5_i                        : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg6_i                        : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg7_i                        : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg8_i                        : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg9_i                        : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg10_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg11_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg12_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg13_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg14_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg15_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg16_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg17_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg18_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg19_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg20_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg21_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg22_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg23_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg24_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg25_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg26_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg27_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg28_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg29_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg30_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg31_i                       : in     std_logic_vector(31 downto 0);
    mf_rx_data_reg32_i                       : in     std_logic_vector(31 downto 0);
    mf_tx_data_ctrl_o                        : out    std_logic_vector(7 downto 0);
    mf_tx_data_reg1_o                        : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg2_o                        : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg3_o                        : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg4_o                        : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg5_o                        : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg6_o                        : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg7_o                        : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg8_o                        : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg9_o                        : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg10_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg11_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg12_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg13_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg14_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg15_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg16_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg17_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg18_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg19_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg20_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg21_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg22_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg23_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg24_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg25_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg26_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg27_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg28_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg29_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg30_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg31_o                       : out    std_logic_vector(31 downto 0);
    mf_tx_data_reg32_o                       : out    std_logic_vector(31 downto 0));
  end component;
  
---------------------------------------------------------------------------------------------------
  component fmc_masterFIP_core is
  generic
    (g_span           : integer := 32;
     g_width          : integer := 32;
     values_for_simul : boolean := FALSE);
  port
    (clk_i       : in    std_logic;
     rst_i       : in    std_logic;
     fd_rxcdn_i  : in    std_logic;
     fd_rxd_i    : in    std_logic;
     fd_txer_i   : in    std_logic;
     fd_wdgn_i   : in    std_logic;
     fd_rstn_o   : out   std_logic;
     fd_txck_o   : out   std_logic;
     fd_txd_o    : out   std_logic;
     fd_txena_o  : out   std_logic;
     irq_p_o     : out   std_logic_vector(7 downto 0);
     aux_o       : out   std_logic_vector(7 downto 0);
     wb_adr_i    : in    std_logic_vector(g_span-1 downto 0);
     wb_dat_i    : in    std_logic_vector(g_width-1 downto 0);
     wb_stb_i    : in    std_logic;
     wb_sel_i    : in    std_logic_vector(3 downto 0);
     wb_we_i     : in    std_logic;
     wb_cyc_i    : in    std_logic;
     wb_ack_o    : out   std_logic;
     wb_stall_o  : out   std_logic;
     wb_dat_o    : out   std_logic_vector(g_width-1 downto 0));
  end component;


---------------------------------------------------------------------------------------------------
  component spec_reset_gen is
  port
    (clk_sys_i        : in std_logic;
     rst_pcie_n_a_i   : in std_logic;
     rst_button_n_a_i : in std_logic;
     rst_n_o          : out std_logic);
  end component;


---------------------------------------------------------------------------------------------------
  component fmc_masterfip_eic
  port
    (rst_n_i                  : in     std_logic;
     clk_sys_i                : in     std_logic;
     wb_adr_i                 : in     std_logic_vector(1 downto 0);
     wb_dat_i                 : in     std_logic_vector(31 downto 0);
     wb_dat_o                 : out    std_logic_vector(31 downto 0);
     wb_cyc_i                 : in     std_logic;
     wb_sel_i                 : in     std_logic_vector(3 downto 0);
     wb_stb_i                 : in     std_logic;
     wb_we_i                  : in     std_logic;
     wb_ack_o                 : out    std_logic;
     wb_stall_o               : out    std_logic;
     wb_int_o                 : out    std_logic;
     irq_macrocy_start_i      : in     std_logic;
     irq_silen_time_expire_i  : in     std_logic;
     irq_turnar_time_expire_i : in     std_logic;
     irq_tx_completed_i       : in     std_logic;
     irq_rx_fss_ok_i          : in     std_logic;
     irq_rx_frame_ok_i        : in     std_logic;
     irq_rx_crc_wrong_i       : in     std_logic);
  end component fmc_masterfip_eic;


---------------------------------------------------------------------------------------------------
  component irq_controller
    port
      (clk_i       : in  std_logic;
       rst_n_i     : in  std_logic;
       irq_src_p_i : in  std_logic_vector(31 downto 0);
       wb_adr_i    : in  std_logic_vector(1 downto 0);
       wb_dat_i    : in  std_logic_vector(31 downto 0);
       wb_cyc_i    : in  std_logic;
       wb_sel_i    : in  std_logic_vector(3 downto 0);
       wb_stb_i    : in  std_logic;
       wb_we_i     : in  std_logic;
      ----------------------------------------------------------------------
       wb_dat_o    : out std_logic_vector(31 downto 0);
       wb_ack_o    : out std_logic;
       irq_p_o     : out std_logic);
  end component irq_controller;


---------------------------------------------------------------------------------------------------
  component carrier_info
    port
      (rst_n_i                           : in  std_logic;
       clk_sys_i                         : in  std_logic;
       wb_adr_i                          : in  std_logic_vector(1 downto 0);
       wb_dat_i                          : in  std_logic_vector(31 downto 0);
       wb_dat_o                          : out std_logic_vector(31 downto 0);
       wb_cyc_i                          : in  std_logic;
       wb_sel_i                          : in  std_logic_vector(3 downto 0);
       wb_stb_i                          : in  std_logic;
       wb_we_i                           : in  std_logic;
       wb_ack_o                          : out std_logic;
       wb_stall_o                        : out std_logic;
       carrier_info_carrier_pcb_rev_i    : in  std_logic_vector(3 downto 0);
       carrier_info_carrier_reserved_i   : in  std_logic_vector(11 downto 0);
       carrier_info_carrier_type_i       : in  std_logic_vector(15 downto 0);
       carrier_info_stat_fmc_pres_i      : in  std_logic;
       carrier_info_stat_p2l_pll_lck_i   : in  std_logic;
       carrier_info_stat_sys_pll_lck_i   : in  std_logic;
       carrier_info_stat_ddr3_cal_done_i : in  std_logic;
       carrier_info_stat_reserved_i      : in  std_logic_vector(27 downto 0);
       carrier_info_ctrl_led_green_o     : out std_logic;
       carrier_info_ctrl_led_red_o       : out std_logic;
       carrier_info_ctrl_dac_clr_n_o     : out std_logic;
       carrier_info_ctrl_reserved_o      : out std_logic_vector(28 downto 0);
       carrier_info_rst_fmc0_n_o         : out std_logic;
       carrier_info_rst_fmc0_n_i         : in  std_logic;
       carrier_info_rst_fmc0_n_load_o    : out std_logic;
       carrier_info_rst_reserved_o       : out std_logic_vector(30 downto 0));
  end component carrier_info;
  
  ---------------------------------------------------------------------------------------------------
  component wf_rx_deserializer
  port (
    uclk_i               : in std_logic;
    nfip_rst_i           : in std_logic;
    rx_rst_i             : in std_logic;
    signif_edge_window_i : in std_logic;
    adjac_bits_window_i  : in std_logic;
    fd_rxd_r_edge_p_i    : in std_logic;
    fd_rxd_f_edge_p_i    : in std_logic;
    fd_rxd_i             : in std_logic;
    sample_manch_bit_p_i : in std_logic;
    sample_bit_p_i       : in std_logic;
  -----------------------------------------------------------------
    byte_ready_p_o       : out std_logic;
    byte_o               : out std_logic_vector (7 downto 0);
    crc_wrong_p_o        : out std_logic;
    fss_crc_fes_ok_p_o   : out std_logic;
    fss_received_p_o     : out std_logic;
    rx_osc_rst_o         : out std_logic);
  -----------------------------------------------------------------
  end component wf_rx_deserializer;

  
---------------------------------------------------------------------------------------------------
  component wf_tx_serializer
  port (
    uclk_i                  : in std_logic;
    nfip_rst_i              : in std_logic;
    byte_i                  : in std_logic_vector (7 downto 0);
    tx_start_p_i            : in std_logic;
    byte_request_accept_p_i : in std_logic; 
    last_byte_p_i           : in std_logic; 
    tx_sched_p_buff_i       : in std_logic_vector (c_TX_SCHED_BUFF_LGTH -1 downto 0);

  -----------------------------------------------------------------
    tx_byte_request_p_o     : out std_logic;
    tx_completed_p_o        : out std_logic;
    tx_osc_rst_p_o          : out std_logic;
    tx_data_o               : out std_logic;
    tx_enable_o             : out std_logic);
  -----------------------------------------------------------------
  end component wf_tx_serializer;

---------------------------------------------------------------------------------------------------
  component masterfip_rx is
  port (
    uclk_i                : in std_logic;
    rate_i                : in std_logic_vector (1 downto 0);
    fd_rxd_a_i            : in std_logic;
    core_rst_i            : in std_logic;
    rx_rst_i              : in std_logic;
  -----------------------------------------------------------------
    rx_byte_index_o      : out std_logic_vector (7 downto 0);
    rx_ctrl_byte_o       : out std_logic_vector (7 downto 0);
    rx_frame_o           : out rx_frame_t; 
    rx_tx_byte_o          : out std_logic_vector (7 downto 0);
    rx_byte_ready_p_o     : out std_logic;
    rx_fss_crc_fes_ok_p_o : out std_logic;
    rx_fss_received_p_o   : out std_logic;
    rx_crc_wrong_p_o      : out std_logic );
  -----------------------------------------------------------------
  end component masterfip_rx;



---------------------------------------------------------------------------------------------------
  component wf_rx_osc is
  port (
    uclk_i                  : in std_logic;
    rate_i                  : in std_logic_vector (1 downto 0);
    nfip_rst_i              : in std_logic;
    fd_rxd_edge_p_i         : in std_logic;
    rx_osc_rst_i            : in std_logic;
  -----------------------------------------------------------------
    rx_manch_clk_p_o        : out std_logic;
    rx_bit_clk_p_o          : out std_logic;
    rx_signif_edge_window_o : out std_logic;
    rx_adjac_bits_window_o  : out std_logic );
  -----------------------------------------------------------------
end component wf_rx_osc;


---------------------------------------------------------------------------------------------------
  component masterfip_tx is
  port (
    uclk_i                     : in std_logic;
    rate_i                     : in std_logic_vector (1 downto 0);
    core_rst_i                 : in std_logic;
    tx_start_p_i               : in std_logic;
    tx_bytes_num_i             : in std_logic_vector (7 downto 0);
    tx_frame_i                 : in tx_frame_t;
    tx_ctrl_byte_i             : in std_logic_vector (7 downto 0);  
  -----------------------------------------------------------------
    tx_byte_index_o            : out std_logic_vector (7 downto 0);
    tx_completed_p_o           : out std_logic;
    tx_data_o                  : out std_logic;
    tx_enable_o                : out std_logic;
    tx_clk_o                   : out std_logic);
  -----------------------------------------------------------------
  end component masterfip_tx;

  

---------------------------------------------------------------------------------------------------
  component wf_tx_osc is
  port (
    uclk_i            : in std_logic;
    rate_i            : in  std_logic_vector (1 downto 0);
    nfip_rst_i        : in std_logic;
    tx_osc_rst_p_i    : in std_logic;
  -----------------------------------------------------------------
    tx_clk_o          : out std_logic;
    tx_sched_p_buff_o : out std_logic_vector (c_TX_SCHED_BUFF_LGTH -1 downto 0));
  -----------------------------------------------------------------
  end component wf_tx_osc;


---------------------------------------------------------------------------------------------------
  component  wf_crc
  port (
    uclk_i             : in std_logic;
    nfip_rst_i         : in std_logic;
    start_crc_p_i      : in std_logic;
    data_bit_i         : in std_logic;
    data_bit_ready_p_i : in std_logic;
  -----------------------------------------------------------------
    crc_ok_p_o         : out std_logic;
    crc_o              : out std_logic_vector (c_CRC_POLY_LGTH - 1 downto 0));
  -----------------------------------------------------------------
  end component wf_crc;



---------------------------------------------------------------------------------------------------
  component wf_manch_encoder is
  generic (g_word_lgth :  natural);
  port (
    word_i       : in std_logic_vector (g_word_lgth-1 downto 0);
  -----------------------------------------------------------------
    word_manch_o : out std_logic_vector ((2*g_word_lgth)-1 downto 0));
  -----------------------------------------------------------------
  end component wf_manch_encoder;



---------------------------------------------------------------------------------------------------
  component wf_rx_deglitcher
  port (
    uclk_i                 : in std_logic;
    nfip_rst_i             : in std_logic;
    fd_rxd_a_i             : in std_logic;
  -----------------------------------------------------------------
    fd_rxd_filt_o          : out std_logic;
    fd_rxd_filt_edge_p_o   : out std_logic;
    fd_rxd_filt_f_edge_p_o : out std_logic);
  -----------------------------------------------------------------
  end component wf_rx_deglitcher;


---------------------------------------------------------------------------------------------------
  component wf_bits_to_txd
  port (
    uclk_i              : in std_logic;
    core_rst_i          : in std_logic;
    txd_bit_index_i     : in unsigned (4 downto 0);
    data_byte_manch_i   : in std_logic_vector (15 downto 0);
    crc_byte_manch_i    : in std_logic_vector (31 downto 0);
    sending_fss_i       : in std_logic;
    sending_data_i      : in std_logic;
    sending_crc_i       : in std_logic;
    sending_fes_i       : in std_logic;
    stop_transmission_i : in std_logic;
    tx_clk_p_i          : in std_logic;
  -----------------------------------------------------------------
    txd_o               : out std_logic;
    tx_enable_o         : out std_logic);
  -----------------------------------------------------------------
  end component wf_bits_to_txd;



---------------------------------------------------------------------------------------------------
  component wf_decr_counter is
  generic (g_counter_lgth :  natural := 5);
  port (
    uclk_i            : in std_logic;
    counter_rst_i     : in std_logic;
    counter_top_i     : in unsigned (g_counter_lgth-1 downto 0);
    counter_load_i    : in std_logic;
    counter_decr_i    : in std_logic;
  -----------------------------------------------------------------
    counter_o         : out unsigned (g_counter_lgth-1 downto 0);
    counter_is_zero_o : out std_logic);
  -----------------------------------------------------------------
  end component wf_decr_counter;



---------------------------------------------------------------------------------------------------
  component wf_incr_counter is
  generic (g_counter_lgth :  natural := 8);
  port (
    uclk_i            : in std_logic;
    counter_reinit_i  : in std_logic;
    counter_incr_i    : in std_logic;
  -----------------------------------------------------------------
    counter_o         : out unsigned (g_counter_lgth-1 downto 0);
    counter_is_full_o : out std_logic);
  -----------------------------------------------------------------
  end component wf_incr_counter;

  
---------------------------------------------------------------------------------------------------
  component decr_counter
    generic
      (width             : integer := 32);
    port
      (clk_i             : in std_logic;
       rst_i             : in std_logic;
       counter_load_i    : in std_logic;
       counter_top_i     : in std_logic_vector(width-1 downto 0);
      -------------------------------------------------------------
       counter_is_zero_o : out std_logic;
       counter_o         : out std_logic_vector(width-1 downto 0));
      -------------------------------------------------------------
  end component;

---------------------------------------------------------------------------------------------------
  function f_manch_encoder (word_i :std_logic_vector) return std_logic_vector;



end masterFIP_pkg;


--=================================================================================================
--                                        package body
--=================================================================================================
package body masterFIP_pkg is


---------------------------------------------------------------------------------------------------
-- Function for the encoding of a word to its Manchester 2 (manch.) equivalent.
-- Each bit "1" is replaced by "10" and each bit "0" by "01".
-- The manch. encoding ensures that there is one transition for each bit.
--   o bit            :    "0"           "1"
--   o manch. encoded :   "0 1"         "1 0"
--   o scheme         :    _|-           -|_

  function f_manch_encoder (word_i : std_logic_vector) return std_logic_vector is

  variable word_manch_o : std_logic_vector ((2*word_i'length) -1 downto 0);

  begin
    for I in word_i'range loop
      word_manch_o (I*2)   := not word_i(I);
      word_manch_o (I*2+1) := word_i(I);
    end loop;
  -----------------------------------------------------------------
    return word_manch_o;
  -----------------------------------------------------------------
  end function;



end masterFIP_pkg;
--=================================================================================================
--                                         package end
--=================================================================================================
---------------------------------------------------------------------------------------------------
--                                      E N D   O F   F I L E
---------------------------------------------------------------------------------------------------