Commit 7ccd991c authored by Pavel Pisa's avatar Pavel Pisa

Merge branch 'master' into master+pci-driver

Driver has been successfully on PCI Devboards Gmb DB4CGX15 card and on Zynq to check that it is correct.

Older (stable) version of CAN CTU FD core has been used for testing.

924e6a00 on Zynq.

7db6025a on DB4CGX15.

Implements #216 (Interfacing CAN FD core to PCI Express bus)

Signed-off-by: Pavel Pisa pisa@cmp.felk.cvut.cz
parents 1e92a553 474daceb
Pipeline #5834 passed with stages
in 12 minutes and 31 seconds
......@@ -533,7 +533,7 @@ Ille Ondrej, Martin Jeřábek
\noindent
\align center
\begin_inset Tabular
<lyxtabular version="3" rows="7" columns="4">
<lyxtabular version="3" rows="8" columns="4">
<features tabularvalignment="middle">
<column alignment="center" valignment="top" width="1.5cm">
<column alignment="center" valignment="top" width="2cm">
......@@ -773,7 +773,7 @@ Added Register map block diagram after re-implementation of registers via
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text
\begin_layout Plain Layout
......@@ -782,7 +782,7 @@ Added Register map block diagram after re-implementation of registers via
\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text
\begin_layout Plain Layout
......@@ -791,7 +791,7 @@ Ondrej Ille
\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text
\begin_layout Plain Layout
......@@ -800,7 +800,7 @@ Ondrej Ille
\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text
\begin_layout Plain Layout
......@@ -808,6 +808,44 @@ Added CRC Wrapper.
Extended CRC description.
\end_layout
\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
\begin_inset Text
\begin_layout Plain Layout
2.1.3
\end_layout
\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
\begin_inset Text
\begin_layout Plain Layout
Ondrej Ille
\end_layout
\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
\begin_inset Text
\begin_layout Plain Layout
01-2019
\end_layout
\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text
\begin_layout Plain Layout
Added TIMESTAMP_LOW, TIMESTAMP_HIGH registers.
\end_layout
\end_inset
</cell>
</row>
......@@ -3163,7 +3201,7 @@ noprefix "false"
\end_inset
lists signals of CTU CAN FD on APB memory interface.
When using CTU CAN FD with Avalon Interface,
When using CTU CAN FD with APB Interface,
\family roman
\shape italic
can_top_apb
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -854,7 +854,7 @@ bool ctu_can_fd_insert_frame(struct ctucanfd_priv *priv, const struct canfd_fram
*/
static inline u16 ctu_can_fd_get_tran_delay(struct ctucanfd_priv *priv)
{
union ctu_can_fd_trv_delay reg;
union ctu_can_fd_trv_delay_ssp_cfg reg;
reg.u32 = priv->read_reg(priv, CTU_CAN_FD_TRV_DELAY);
return reg.s.trv_delay_value;
}
......
......@@ -80,10 +80,13 @@ enum ctu_can_fd_can_registers {
CTU_CAN_FD_ERR_CAPT = 0x74,
CTU_CAN_FD_ALC = 0x75,
CTU_CAN_FD_TRV_DELAY = 0x78,
CTU_CAN_FD_SSP_CFG = 0x7a,
CTU_CAN_FD_RX_COUNTER = 0x7c,
CTU_CAN_FD_TX_COUNTER = 0x80,
CTU_CAN_FD_DEBUG_REGISTER = 0x84,
CTU_CAN_FD_YOLO_REG = 0x88,
CTU_CAN_FD_TIMESTAMP_LOW = 0x8c,
CTU_CAN_FD_TIMESTAMP_HIGH = 0x90,
CTU_CAN_FD_TXTB1_DATA_1 = 0x100,
CTU_CAN_FD_TXTB1_DATA_2 = 0x104,
CTU_CAN_FD_TXTB1_DATA_20 = 0x14c,
......@@ -841,20 +844,33 @@ enum ctu_can_fd_alc_alc_id_field {
ALC_RTR = 0x4,
};
union ctu_can_fd_trv_delay {
union ctu_can_fd_trv_delay_ssp_cfg {
uint32_t u32;
struct ctu_can_fd_trv_delay_s {
struct ctu_can_fd_trv_delay_ssp_cfg_s {
#ifdef __LITTLE_ENDIAN_BITFIELD
/* TRV_DELAY */
uint32_t trv_delay_value : 16;
uint32_t reserved_31_16 : 16;
/* SSP_CFG */
uint32_t ssp_offset : 7;
uint32_t reserved_23 : 1;
uint32_t ssp_src : 2;
uint32_t reserved_31_26 : 6;
#else
uint32_t reserved_31_16 : 16;
uint32_t reserved_31_26 : 6;
uint32_t ssp_src : 2;
uint32_t reserved_23 : 1;
uint32_t ssp_offset : 7;
uint32_t trv_delay_value : 16;
#endif
} s;
};
enum ctu_can_fd_ssp_cfg_ssp_src {
SSP_SRC_MEASURED = 0x0,
SSP_SRC_MEAS_N_OFFSET = 0x1,
SSP_SRC_OFFSET = 0x2,
};
union ctu_can_fd_rx_counter {
uint32_t u32;
struct ctu_can_fd_rx_counter_s {
......@@ -909,6 +925,22 @@ union ctu_can_fd_yolo_reg {
} s;
};
union ctu_can_fd_timestamp_low {
uint32_t u32;
struct ctu_can_fd_timestamp_low_s {
/* TIMESTAMP_LOW */
uint32_t timestamp_low : 32;
} s;
};
union ctu_can_fd_timestamp_high {
uint32_t u32;
struct ctu_can_fd_timestamp_high_s {
/* TIMESTAMP_HIGH */
uint32_t timestamp_high : 32;
} s;
};
union ctu_can_fd_log_trig_config {
uint32_t u32;
struct ctu_can_fd_log_trig_config_s {
......
Subproject commit 9fbe789631055fc887a4124b7a23e4d04a6863cf
Subproject commit 24f6fe411be6ed81ce4ab27d2dfeadaca425d999
......@@ -159,14 +159,14 @@ if __name__ == '__main__':
licensePath=MIT_LICENSE_PATH,
memMap="CAN_Registers",
wordWidthBit=32,
outPath="../src/Libraries/CAN_FD_register_map.vhd",
outPath="../src/lib/can_fd_register_map.vhd",
packName="can_fd_register_map")
ctu_can_update_vhdl_package(specPath=args.xactSpec,
licensePath=MIT_LICENSE_PATH,
memMap="CAN_Frame_format",
wordWidthBit=32,
outPath="../src/Libraries/CAN_FD_frame_format.vhd",
outPath="../src/lib/can_fd_frame_format.vhd",
packName="can_fd_frame_format")
print("\nDone\n")
......@@ -233,7 +233,7 @@ if __name__ == '__main__':
licensePath=MIT_LICENSE_PATH,
memMap="CAN_Registers",
wordWidthBit=32,
outDir="../../src/Registers_Memory_Interface/generated")
outDir="../../src/memory_registers/generated")
# Frame format map not implemented as RTL, virtual map for frame format
# visualisaion only
......
This diff is collapsed.
--------------------------------------------------------------------------------
--
-- CTU CAN FD IP Core
-- Copyright (C) 2015-2018
--
-- Authors:
-- Ondrej Ille <ondrej.ille@gmail.com>
-- Martin Jerabek <martin.jerabek01@gmail.com>
--
-- Project advisors:
-- Jiri Novak <jnovak@fel.cvut.cz>
-- Pavel Pisa <pisa@cmp.felk.cvut.cz>
--
-- Department of Measurement (http://meas.fel.cvut.cz/)
-- Faculty of Electrical Engineering (http://www.fel.cvut.cz)
-- Czech Technical University (http://www.cvut.cz/)
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this VHDL component and associated documentation files (the "Component"),
-- to deal in the Component without restriction, including without limitation
-- the rights to use, copy, modify, merge, publish, distribute, sublicense,
-- and/or sell copies of the Component, and to permit persons to whom the
-- Component is furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Component.
--
-- THE COMPONENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS
-- IN THE COMPONENT.
--
-- The CAN protocol is developed by Robert Bosch GmbH and protected by patents.
-- Anybody who wants to implement this IP core on silicon has to obtain a CAN
-- protocol license from Bosch.
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Purpose:
-- Detection of edge on TX and RX data. Selectable DFF may be inserted on
-- output.
--
-- Edge on RX Data is signaled only when:
-- 1. Edge is detected on "rx_edge" input
-- 2. Previously sampled value of RX data is different from value after
-- the edge.
-- 3. Actual value of data is DOMINANT.
-- By these conditions it is satisfied that only RECESSIE to DOMINANT edge
-- with previous bit value detected as RECESSIVE is signalled. In CAN, this
-- is the only valid, HARD SYNCHRONISATION or RE-SYNCHRONISATION edge.
--
-- Edge on TX Data is signalled only when:
-- 1. There is an edge on TX Data.
-- 2. New TX-Data are dominant.
--
-- TX Edge is used for TRV DELAY measurement which is in EDL to R0 edge.
-- Thus only RECESSIVE to DOMINANT edge is needed.
--
--------------------------------------------------------------------------------
-- 05.01.2018 Created file
--------------------------------------------------------------------------------
Library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.ALL;
use ieee.math_real.ALL;
Library work;
use work.id_transfer.all;
use work.can_constants.all;
use work.can_components.all;
use work.can_types.all;
use work.cmn_lib.all;
use work.drv_stat_pkg.all;
use work.endian_swap.all;
use work.reduce_lib.all;
use work.CAN_FD_register_map.all;
use work.CAN_FD_frame_format.all;
entity data_edge_detector is
generic(
-- Reset polarity
constant reset_polarity : std_logic;
-- Pipeline TX edge output (insert DFF)
constant tx_edge_pipeline : boolean := true;
-- Pipeline RX edge output (insert DFF)
constant rx_edge_pipeline : boolean := true
);
port(
------------------------------------------------------------------------
-- Clock and Async reset
------------------------------------------------------------------------
signal clk_sys :in std_logic;
signal res_n :in std_logic;
------------------------------------------------------------------------
-- Inputs
------------------------------------------------------------------------
-- TX Data from CAN Core
signal tx_data :in std_logic;
-- RX Data (synced from CAN Bus)
signal rx_data :in std_logic;
-- RX Data value sampled in previous Sample point.
signal prev_rx_sample :in std_logic;
------------------------------------------------------------------------
-- Outputs
------------------------------------------------------------------------
-- Edge detected on TX
signal tx_edge :out std_logic;
-- Edge detected on RX
signal rx_edge :out std_logic
);
end entity;
architecture rtl of data_edge_detector is
-- Previous values on rx_data, tx_data inputs to detect edge
signal rx_data_prev : std_logic;
signal tx_data_prev : std_logic;
-- Immediate edges on tx_data, rx_data (not yet finally valid)
signal rx_edge_immediate : std_logic;
signal tx_edge_immediate : std_logic;
-- Valid edge
signal rx_edge_valid : std_logic;
signal tx_edge_valid : std_logic;
-- Internal value of output signals
signal rx_edge_i : std_logic;
signal tx_edge_i : std_logic;
begin
----------------------------------------------------------------------------
-- Registering previous value of rx_data, tx_data to detect edge in
-- the stream
----------------------------------------------------------------------------
data_reg_proc : process(clk_sys, res_n)
begin
if (res_n = reset_polarity) then
rx_data_prev <= RECESSIVE;
tx_data_prev <= RECESSIVE;
elsif (rising_edge(clk_sys)) then
rx_data_prev <= rx_data;
tx_data_prev <= tx_data;
end if;
end process;
----------------------------------------------------------------------------
-- Immediate edges are detected when there is difference between input
-- data (TX,RX) and its registered version.
----------------------------------------------------------------------------
rx_edge_immediate <= '1' when (rx_data_prev /= rx_data) else
'0';
tx_edge_immediate <= '1' when (tx_data_prev /= tx_data) else
'0';
----------------------------------------------------------------------------
-- Valid TX Edge:
-- 1. Edge on tx_data
-- 2. RECESSIVE to DOMINANT
----------------------------------------------------------------------------
tx_edge_valid <= '1' when (tx_edge_immediate = '1') and
(tx_data_prev = RECESSIVE)
else
'0';
----------------------------------------------------------------------------
-- Valid RX Edge:
-- 1. Edge on rx_data
-- 2. RECESSIVE to DOMINANT
-- 3. Data sampled in previous Sample point are different from actual
-- rx_data immediately after edge.
----------------------------------------------------------------------------
rx_edge_valid <= '1' when (rx_edge_immediate = '1') and
(rx_data_prev = RECESSIVE) and
(prev_rx_sample /= rx_data)
else
'0';
----------------------------------------------------------------------------
-- Driving rx_edge output
----------------------------------------------------------------------------
rx_edge_pipeline_gen_true : if (rx_edge_pipeline) generate
rx_edge_pipeline_proc : process(res_n, clk_sys)
begin
if (res_n = reset_polarity) then
rx_edge_i <= '0';
elsif (rising_edge(clk_sys)) then
rx_edge_i <= rx_edge_valid;
end if;
end process;
end generate rx_edge_pipeline_gen_true;
rx_edge_pipeline_gen_false : if (not rx_edge_pipeline) generate
rx_edge_i <= rx_edge_valid;
end generate rx_edge_pipeline_gen_false;
rx_edge <= rx_edge_i;
----------------------------------------------------------------------------
-- Driving tx_edge output
----------------------------------------------------------------------------
tx_edge_pipeline_gen_true : if (tx_edge_pipeline) generate
tx_edge_pipeline_proc : process(res_n, clk_sys)
begin
if (res_n = reset_polarity) then
tx_edge_i <= '0';
elsif (rising_edge(clk_sys)) then
tx_edge_i <= tx_edge_valid;
end if;
end process;
end generate tx_edge_pipeline_gen_true;
tx_edge_pipeline_gen_false : if (not tx_edge_pipeline) generate
tx_edge_i <= tx_edge_valid;
end generate tx_edge_pipeline_gen_false;
tx_edge <= tx_edge_i;
end architecture;
This diff is collapsed.
......@@ -144,6 +144,8 @@ end entity;
architecture rtl of bit_stuffing is
signal data_out_int : std_logic;
---------------------------------------------------------------------------
-- Counter with number of equal consequent bits
---------------------------------------------------------------------------
......@@ -226,6 +228,8 @@ architecture rtl of bit_stuffing is
begin
data_out <= data_out_int;
---------------------------------------------------------------------------
-- Registering previous value of enable input to detect 0->1 transition.
---------------------------------------------------------------------------
......@@ -322,7 +326,7 @@ begin
---------------------------------------------------------------------------
same_bits_rst_trig <= '1' when (non_fix_to_fix_chng = '1') or
(stuff_lvl_reached = '1') or
(data_in /= data_out and fixed_stuff = '0')
(data_in /= data_out_int and fixed_stuff = '0')
else
'0';
......@@ -406,13 +410,13 @@ begin
-- 4. Keep previous value otherwise
---------------------------------------------------------------------------
data_out_nxt_ena <= RECESSIVE when (enable_prev = '0') else
(not data_out) when (tran_trig_1 = '1' and insert_stuff_bit = '1') else
(not data_out_int) when (tran_trig_1 = '1' and insert_stuff_bit = '1') else
data_in when (tran_trig_1 = '1') else
data_out;
data_out_int;
data_out_nxt <= data_out_nxt_ena when (enable = '1') else
data_in when (tran_trig_1 = '1') else
data_out;
data_out_int;
data_out_load <= '1' when (enable = '1' or tran_trig_1 = '1') else
'0';
......@@ -433,7 +437,7 @@ begin
input => data_out_nxt,
load => data_out_load,
output => data_out
output => data_out_int
);
......
......@@ -92,6 +92,9 @@ end entity;
architecture rtl of bus_traffic_counters is
signal tx_ctr_int : std_logic_vector(31 downto 0);
signal rx_ctr_int : std_logic_vector(31 downto 0);
-- Input selector
signal sel : std_logic;
......@@ -103,13 +106,16 @@ architecture rtl of bus_traffic_counters is
begin
tx_ctr <= tx_ctr_int;
rx_ctr <= rx_ctr_int;
-- Input selector
sel <= '1' when (inc_tx_ctr = '1') else
'0';
-- Multiplexor between TX and RX value to increment
sel_value <= tx_ctr when (sel = '1') else
rx_ctr;
sel_value <= tx_ctr_int when (sel = '1') else
rx_ctr_int;
-- Incremented value of either TX or RX counter
inc_value <= std_logic_vector(to_unsigned(
......@@ -121,11 +127,11 @@ begin
tx_ctr_proc : process(clk_sys, res_n)
begin
if (res_n = ACT_RESET or clear_tx_ctr = '1') then
tx_ctr <= (OTHERS => '0');
tx_ctr_int <= (OTHERS => '0');
elsif rising_edge(clk_sys) then
if (inc_tx_ctr = '1') then
tx_ctr <= inc_value;
tx_ctr_int <= inc_value;
end if;
end if;
end process;
......@@ -137,11 +143,11 @@ begin
rx_ctr_proc : process(clk_sys, res_n)
begin
if (res_n = ACT_RESET or clear_rx_ctr = '1') then
rx_ctr <= (OTHERS => '0');
rx_ctr_int <= (OTHERS => '0');
elsif rising_edge(clk_sys) then
if (inc_rx_ctr = '1') then
rx_ctr <= inc_value;
rx_ctr_int <= inc_value;
end if;
end if;
end process;
......
......@@ -399,7 +399,7 @@ architecture rtl of CAN_top_level is
signal br_shifted : std_logic;
--Event logging finsihed
signal loger_finished : std_logic;
signal loger_finished : std_logic;
----------------------------------------------------------------------------
......@@ -536,6 +536,7 @@ begin
srd => srd,
swr => swr,
sbe => sbe,
timestamp => timestamp,
drv_bus => drv_bus,
stat_bus => stat_bus,
rx_read_buff => rx_read_buff,
......
This diff is collapsed.
......@@ -193,6 +193,26 @@ architecture rtl of int_manager is
constant zero_mask : std_logic_vector(int_count - 1 downto 0)
:= (OTHERS => '0');
----------------------------------------------------------------------------
-- Reset over set priority assignment
----------------------------------------------------------------------------
type int_s_r_priority_type is array(0 to int_count - 1) of boolean;
constant int_clear_priority : int_s_r_priority_type :=
(false, -- RXI_IND
false, -- TXI_IND
false, -- EWLI_IND
true, -- DOI_IND
false, -- EPI_IND
false, -- ALI_IND
false, -- BEI_IND
false, -- LFI_IND
false, -- RXFI_IND
false, -- BSI_IND
false, -- RBNEI_IND
false -- TXBHCI_IND
);
begin
......@@ -222,13 +242,13 @@ begin
---------------------------------------------------------------------------
-- Interrupt register masking and enabling
---------------------------------------------------------------------------
int_input_active(BEI_IND) <= error_valid;
int_input_active(ALI_IND) <= arbitration_lost;
int_input_active(EPI_IND) <= error_passive_changed;
int_input_active(DOI_IND) <= rx_message_disc;
int_input_active(EWLI_IND) <= error_warning_limit;
int_input_active(TXI_IND) <= tx_finished;
int_input_active(RXI_IND) <= rec_message_valid;
int_input_active(TXI_IND) <= tx_finished;
int_input_active(EWLI_IND) <= error_warning_limit;
int_input_active(DOI_IND) <= rx_message_disc;
int_input_active(EPI_IND) <= error_passive_changed;
int_input_active(ALI_IND) <= arbitration_lost;
int_input_active(BEI_IND) <= error_valid;
int_input_active(LFI_IND) <= loger_finished;
int_input_active(RXFI_IND) <= rx_full;
int_input_active(BSI_IND) <= br_shifted;
......@@ -244,7 +264,7 @@ begin
int_module_comp : int_module
generic map(
reset_polarity => ACT_RESET,
clear_priority => false
clear_priority => int_clear_priority(i)
)
port map(
clk_sys => clk_sys,
......
......@@ -140,6 +140,7 @@ package can_components is
signal srd : in std_logic;
signal swr : in std_logic;
signal sbe : in std_logic_vector(3 downto 0);
signal timestamp : in std_logic_vector(63 downto 0);
signal drv_bus : out std_logic_vector(1023 downto 0);
signal stat_bus : in std_logic_vector(511 downto 0);
signal rx_read_buff : in std_logic_vector(31 downto 0);
......@@ -754,6 +755,50 @@ package can_components is
end component;
----------------------------------------------------------------------------
-- Data edge detector
----------------------------------------------------------------------------
component data_edge_detector is
generic(
constant reset_polarity : std_logic;
constant tx_edge_pipeline : boolean := true;
constant rx_edge_pipeline : boolean := true
);
port(
signal clk_sys :in std_logic;
signal res_n :in std_logic;
signal tx_data :in std_logic;
signal rx_data :in std_logic;
signal prev_rx_sample :in std_logic;
signal tx_edge :out std_logic;
signal rx_edge :out std_logic
);
end component;
----------------------------------------------------------------------------
-- Transceiver Delay measurement
----------------------------------------------------------------------------
component trv_delay_measurement is
generic(
constant reset_polarity : std_logic;
constant trv_ctr_width : natural := 7;
constant use_ssp_saturation : boolean := true;
constant ssp_saturation_lvl : natural
);
port(
signal clk_sys :in std_logic;
signal res_n :in std_logic;
signal meas_start :in std_logic;
signal meas_stop :in std_logic;
signal meas_enable :in std_logic;
signal ssp_offset :in std_logic_vector(trv_ctr_width - 1 downto 0);
signal ssp_delay_select :in std_logic_vector(1 downto 0);
signal trv_meas_progress :out std_logic;
signal trv_delay_shadowed :out std_logic_vector(trv_ctr_width - 1 downto 0);
signal ssp_delay_shadowed :out std_logic_vector(trv_ctr_width downto 0)
);
end component;
----------------------------------------------------------------------------
-- Event Logger module
----------------------------------------------------------------------------
......
......@@ -98,10 +98,13 @@ package can_fd_register_map is
constant ERR_CAPT_ADR : std_logic_vector(11 downto 0) := x"074";
constant ALC_ADR : std_logic_vector(11 downto 0) := x"075";
constant TRV_DELAY_ADR : std_logic_vector(11 downto 0) := x"078";
constant SSP_CFG_ADR : std_logic_vector(11 downto 0) := x"07A";
constant RX_COUNTER_ADR : std_logic_vector(11 downto 0) := x"07C";
constant TX_COUNTER_ADR : std_logic_vector(11 downto 0) := x"080";