From 748b9d26641366e70d3fdb2fc7a4db8bbce34b2b Mon Sep 17 00:00:00 2001 From: Michael Boehmer Date: Sun, 31 Jul 2022 09:41:36 +0200 Subject: [PATCH] cleanup --- gbe_trb/base/gbe_wrapper_fifo.vhd | 4 +- gbe_trb/base/rx_rb.vhd | 177 ++++++++++++++++------------ gbe_trb/base/sgl_ctrl.vhd | 4 +- gbe_trb/base/tx_fifo.vhd | 12 +- gbe_trb_ecp3/base/gbe_med_fifo.vhd | 8 +- gbe_trb_ecp5/media/gbe_med_fifo.vhd | 105 ++++++++++------- 6 files changed, 173 insertions(+), 137 deletions(-) diff --git a/gbe_trb/base/gbe_wrapper_fifo.vhd b/gbe_trb/base/gbe_wrapper_fifo.vhd index 7bd606d..dab24a6 100644 --- a/gbe_trb/base/gbe_wrapper_fifo.vhd +++ b/gbe_trb/base/gbe_wrapper_fifo.vhd @@ -137,9 +137,7 @@ begin FRAME_REQ_IN => FRAME_REQ_IN, FRAME_ACK_OUT => FRAME_ACK_OUT, FRAME_AVAIL_OUT => FRAME_AVAIL_OUT, - FRAME_START_OUT => FRAME_START_OUT, - -- - DEBUG => open + FRAME_START_OUT => FRAME_START_OUT ); ------------------------------------------------------------------------------------------------- diff --git a/gbe_trb/base/rx_rb.vhd b/gbe_trb/base/rx_rb.vhd index 31f3f5e..c6e1b76 100644 --- a/gbe_trb/base/rx_rb.vhd +++ b/gbe_trb/base/rx_rb.vhd @@ -21,12 +21,22 @@ entity rx_rb is FRAME_REQ_IN : in std_logic; -- one pulse starts readout of frame stored in ring buffer FRAME_ACK_OUT : out std_logic; -- one pulse for "end of frame" FRAME_AVAIL_OUT : out std_logic; -- number of frames stored in ring buffer - FRAME_START_OUT : out std_logic; -- StartOfFrame signal - -- - DEBUG : out std_logic_vector(15 downto 0) + FRAME_START_OUT : out std_logic -- StartOfFrame signal ); end entity rx_rb; +-- This entity acts as receiv buffer for the new GbE media interface. It connects to the MAC RX ports, +-- and is storing incoming Ethernet frames. +-- Broken frames (indicated by MAC_RX_ERROR_IN) are dropped, and in addition, frames which can't be stored +-- completely (due to potential ring buffer overflow) are also dropped. +-- This entity can forward frames on request by doing "DMA": +-- If a frame is requested by FRAME_REQ_IN, the entity decides if a full frame is available (as shown by +-- FRAME_AVAIL_OUT), in case no data is present, a FRAME_ACK_OUT is generated to avoid deadlocks, but +-- no data is transfered. +-- If a frame can be transfered, FRAME_START_OUT is set for one cycle, and data is written out +-- (handshaking with FIFO_FULL_IN) on FIFO_Q_OUT, with data validated by FIFO_WR_OUT. +-- With the EOF signal (FIFO_Q_OUT(8)) set FRAME_ACK_OUT is also set and the transfer ends. + architecture rx_rb_arch of rx_rb is -- Components @@ -53,29 +63,30 @@ architecture rx_rb_arch of rx_rb is signal rd_ptr : unsigned(11 downto 0); signal wr_ptr : unsigned(11 downto 0); signal last_wr_ptr : std_logic_vector(11 downto 0); - signal rb_used : unsigned(11 downto 0); - signal rb_full : std_logic; - signal rb_empty : std_logic; - signal ce_wr_ptr : std_logic; - signal ld_wr_ptr : std_logic; - signal ce_rd_ptr : std_logic; - signal wr_ram : std_logic; - signal rd_ram : std_logic; + signal rb_used_x : unsigned(11 downto 0); + signal rb_full_x : std_logic; + signal rb_empty_x : std_logic; + signal ce_wr_ptr_x : std_logic; + signal ld_wr_ptr_x : std_logic; + signal ce_rd_ptr_x : std_logic; + signal wr_ram_x : std_logic; + signal rd_ram_x : std_logic; signal ram_q : std_logic_vector(8 downto 0); - signal frame_active : std_logic; signal frame_requested : std_logic; signal frame_acknowledged : std_logic; signal fifo_wr_int : std_logic; signal empty_read_ack : std_logic; - signal normal_read_ack : std_logic; + signal normal_read_ack_x : std_logic; signal sof_int : std_logic; signal frames_avail : unsigned(7 downto 0); - - + signal frame_active : std_logic; + signal frame_error : std_logic; + begin -- FrameActive: we must not change to "receive" in the middle of a frame - -- when "buffer full" condition is deasserted + -- when "buffer full" condition is deasserted. + -- Needs to be extra process, not inside the state machine! THE_FRAME_ACTIVE_PROC: process( CLK ) begin if( rising_edge(CLK) ) then @@ -89,56 +100,57 @@ begin end if; end process THE_FRAME_ACTIVE_PROC; + -- Read pointer for ring buffer + THE_RD_PTR_PROC: process( CLK ) + begin + if( rising_edge(CLK) ) then + if ( RESET = '1' ) then + rd_ptr <= (others => '0'); + elsif( ce_rd_ptr_x = '1' ) then + rd_ptr <= rd_ptr + 1; + end if; + end if; + end process THE_RD_PTR_PROC; + -- Write pointer for ring buffer THE_WR_PTR_PROC: process( CLK ) begin if( rising_edge(CLK) ) then if ( RESET = '1' ) then wr_ptr <= (others => '0'); - elsif( ld_wr_ptr = '1' ) then + elsif( ld_wr_ptr_x = '1' ) then wr_ptr <= unsigned(last_wr_ptr); - elsif( ce_wr_ptr = '1' ) then + elsif( ce_wr_ptr_x = '1' ) then wr_ptr <= wr_ptr + 1; end if; end if; end process THE_WR_PTR_PROC; - -- Read pointer for ring buffer - THE_RD_PTR_PROC: process( CLK ) + -- last write pointer: used to drop a broken frame, in case + THE_LAST_WR_PTR_PROC: process( CLK ) begin if( rising_edge(CLK) ) then if ( RESET = '1' ) then - rd_ptr <= (others => '0'); - elsif( ce_rd_ptr = '1' ) then - rd_ptr <= rd_ptr + 1; + last_wr_ptr <= (others => '0'); + elsif( (STATE = RX_READY) and (MAC_RX_WR_IN = '1') ) then + last_wr_ptr <= std_logic_vector(wr_ptr); end if; end if; - end process THE_RD_PTR_PROC; + end process THE_LAST_WR_PTR_PROC; -- ring buffer fill level - rb_used <= wr_ptr - rd_ptr; + rb_used_x <= wr_ptr - rd_ptr; -- ring buffer full -- TAKE CARE: the last byte of a frame is taken into account -- by "one less" for the full condition - rb_full <= '1' when (rb_used(11 downto 1) = b"1111_1111_111") else '0'; + rb_full_x <= '1' when (rb_used_x(11 downto 1) = b"1111_1111_111") else '0'; - rb_empty <= '1' when (rb_used(11 downto 0) = b"0000_0000_0000") else '0'; + -- ring buffer empty + rb_empty_x <= '1' when (rb_used_x(11 downto 0) = b"0000_0000_0000") else '0'; - MAC_RX_FIFOFULL_OUT <= rb_full; + MAC_RX_FIFOFULL_OUT <= rb_full_x; - -- last write pointer: used to drop a broken frame, in case - THE_LAST_WR_PTR_PROC: process( CLK ) - begin - if( rising_edge(CLK) ) then - if ( RESET = '1' ) then - last_wr_ptr <= (others => '0'); - elsif( (STATE = RX_READY) and (MAC_RX_WR_IN = '1') ) then - last_wr_ptr <= std_logic_vector(wr_ptr); - end if; - end if; - end process THE_LAST_WR_PTR_PROC; - -- DPRAM as ring buffer THE_DP_RAM: rb_4k_9 port map( @@ -146,7 +158,7 @@ begin RDADDRESS => std_logic_vector(rd_ptr), DATA(8) => MAC_RX_EOF_IN, DATA(7 downto 0) => MAC_RX_DATA_IN, - WE => wr_ram, + WE => wr_ram_x, RDCLOCK => CLK, RDCLOCKEN => '1', RESET => RESET, @@ -155,14 +167,28 @@ begin Q => ram_q ); - -- write signal - wr_ram <= '1' when ((STATE = RX_READY) and (MAC_RX_WR_IN = '1') and (rb_full = '0')) or - ((STATE = RX_FRAME) and (MAC_RX_WR_IN = '1') and (rb_full = '0')) - else '0'; - ce_wr_ptr <= '1' when ((STATE = RX_READY) and (MAC_RX_WR_IN = '1') and (rb_full = '0')) or - ((STATE = RX_FRAME) and (MAC_RX_WR_IN = '1') and (rb_full = '0')) - else '0'; + -- write signal + wr_ram_x <= '1' when ((STATE = RX_READY) and (MAC_RX_WR_IN = '1') and (rb_full_x = '0')) or -- first byte of frame + ((STATE = RX_FRAME) and (MAC_RX_WR_IN = '1') and (rb_full_x = '0')) -- all other bytes of frame + else '0'; + ce_wr_ptr_x <= '1' when ((STATE = RX_READY) and (MAC_RX_WR_IN = '1') and (rb_full_x = '0')) or + ((STATE = RX_FRAME) and (MAC_RX_WR_IN = '1') and (rb_full_x = '0')) + else '0'; + -- FrameError: catches problem with FIFOFULL during a frame write. + THE_FRAME_ERROR_PROC: process( CLK ) + begin + if( rising_edge(CLK) ) then + if ( RESET = '1' ) then + frame_error <= '0'; + elsif( (frame_active = '1') and (rb_full_x = '1') and (MAC_RX_WR_IN = '1') ) then + frame_error <= '1'; + elsif( (frame_active = '0') ) then -- could be better! + frame_error <= '0'; + end if; + end if; + end process THE_FRAME_ERROR_PROC; + -- FrameReq signal, one pulse only THE_FRAME_REQ_PROC: process( CLK ) begin @@ -176,29 +202,24 @@ begin end if; end if; end process THE_FRAME_REQ_PROC; - - -- EmptyReadAck signal, used to handle a request to RX_RB with no frame to send - empty_read_ack <= FRAME_REQ_IN and rb_empty when rising_edge(CLK); - -- NormalReadAck signal --- normal_read_ack <= ram_q(8) and fifo_wr_int when rising_edge(CLK); -- ADDED 2nd step - normal_read_ack <= ram_q(8) and fifo_wr_int; + -- NormalReadAck signal: ends a normal data transfer by EOF + normal_read_ack_x <= ram_q(8) and fifo_wr_int; -- read signal - rd_ram <= '1' when ((frame_requested = '1') and (ram_q(8) = '0') and (FIFO_FULL_IN = '0') and (rb_empty = '0')) else '0'; - ce_rd_ptr <= '1' when ((frame_requested = '1') and (ram_q(8) = '0') and (FIFO_FULL_IN = '0') and (rb_empty = '0')) else '0'; - - sof_int <= FRAME_REQ_IN and not frame_requested when rising_edge(CLK); - - FRAME_ACK_OUT <= normal_read_ack or empty_read_ack when rising_edge(CLK); -- ADDED - - FRAME_START_OUT <= sof_int when rising_edge(CLK); -- ADDED - - FIFO_Q_OUT <= ram_q when rising_edge(CLK); -- ADDED - - fifo_wr_int <= rd_ram when rising_edge(CLK); - - FIFO_WR_OUT <= fifo_wr_int when rising_edge(CLK); -- ADDED + rd_ram_x <= '1' when ((frame_requested = '1') and (ram_q(8) = '0') and (FIFO_FULL_IN = '0') and (rb_empty_x = '0')) else '0'; + ce_rd_ptr_x <= '1' when ((frame_requested = '1') and (ram_q(8) = '0') and (FIFO_FULL_IN = '0') and (rb_empty_x = '0')) else '0'; + +-- THE_SYNC_PROC: process( CLK ) +-- begin + empty_read_ack <= FRAME_REQ_IN and rb_empty_x when rising_edge(CLK); + sof_int <= FRAME_REQ_IN and not frame_requested when rising_edge(CLK); + FRAME_START_OUT <= sof_int when rising_edge(CLK); + fifo_wr_int <= rd_ram_x when rising_edge(CLK); + FIFO_WR_OUT <= fifo_wr_int when rising_edge(CLK); + FRAME_ACK_OUT <= normal_read_ack_x or empty_read_ack when rising_edge(CLK); + FIFO_Q_OUT <= ram_q when rising_edge(CLK); +-- end process THE_SYNC_PROC; -- FramesAvailable counter THE_FRAMES_AVAIL_PROC: process( CLK ) @@ -206,10 +227,10 @@ begin if( rising_edge(CLK) ) then if ( RESET = '1' ) then frames_avail <= (others => '0'); - elsif( (STATE = FRAME_OK) and (normal_read_ack = '0') ) then + elsif( (STATE = FRAME_OK) and (normal_read_ack_x = '0') ) then -- one frame written successfully frames_avail <= frames_avail + 1; - elsif( (STATE /= FRAME_OK) and (normal_read_ack = '1') ) then + elsif( (STATE /= FRAME_OK) and (normal_read_ack_x = '1') ) then -- one frame read successfully frames_avail <= frames_avail - 1; end if; @@ -232,14 +253,14 @@ begin end if; end process THE_FSM; - THE_STATE_TRANSITIONS: process( STATE, MAC_RX_WR_IN, MAC_RX_EOF_IN, MAC_RX_ERROR_IN, frame_active, rb_full ) + THE_STATE_TRANSITIONS: process( STATE, MAC_RX_WR_IN, MAC_RX_EOF_IN, MAC_RX_ERROR_IN, frame_active, rb_full_x ) begin - ld_wr_ptr <= '0'; + ld_wr_ptr_x <= '0'; case STATE is when RX_DENY => - if( (frame_active = '0') and (rb_full = '0') ) then + if( (frame_active = '0') and (rb_full_x = '0') ) then NEXT_STATE <= RX_READY; else NEXT_STATE <= RX_DENY; @@ -253,11 +274,11 @@ begin end if; when RX_FRAME => - if ( (MAC_RX_EOF_IN = '1') and (MAC_RX_ERROR_IN = '0') and (rb_full = '0') ) then + if ( (MAC_RX_EOF_IN = '1') and (MAC_RX_ERROR_IN = '0') and (rb_full_x = '0') ) then NEXT_STATE <= FRAME_OK; - elsif( (MAC_RX_EOF_IN = '1') and ((MAC_RX_ERROR_IN = '1') or (rb_full = '1')) ) then + elsif( (MAC_RX_EOF_IN = '1') and ((MAC_RX_ERROR_IN = '1') or (rb_full_x = '1')) ) then NEXT_STATE <= FRAME_BAD; - ld_wr_ptr <= '1'; + ld_wr_ptr_x <= '1'; else NEXT_STATE <= RX_FRAME; end if; @@ -266,7 +287,7 @@ begin NEXT_STATE <= FORWARD; when FORWARD => - if( rb_full = '0' ) then + if( rb_full_x = '0' ) then NEXT_STATE <= RX_READY; else NEXT_STATE <= RX_DENY; @@ -276,7 +297,7 @@ begin NEXT_STATE <= SKIP; when SKIP => - if( rb_full = '0' ) then + if( rb_full_x = '0' ) then NEXT_STATE <= RX_READY; else NEXT_STATE <= RX_DENY; diff --git a/gbe_trb/base/sgl_ctrl.vhd b/gbe_trb/base/sgl_ctrl.vhd index ad79d4d..e1249fa 100644 --- a/gbe_trb/base/sgl_ctrl.vhd +++ b/gbe_trb/base/sgl_ctrl.vhd @@ -29,9 +29,8 @@ entity sgl_ctrl is DL_TX_PORT_SEL_OUT : out std_logic; -- '0' => LOCAL, '1' UL LOCAL_TX_PORT_SEL_OUT : out std_logic; UL_TX_PORT_SEL_OUT : out std_logic; - -- - DEBUG : out std_logic_vector(15 downto 0) + DEBUG : out std_logic_vector(15 downto 0) ); end entity sgl_ctrl; @@ -229,7 +228,6 @@ begin local_tx_port_sel_x <= '0'; ul_tx_port_sel_x <= '0'; - case STATE is when IDLE => bsm <= x"0"; diff --git a/gbe_trb/base/tx_fifo.vhd b/gbe_trb/base/tx_fifo.vhd index 9bd55d9..940d72a 100644 --- a/gbe_trb/base/tx_fifo.vhd +++ b/gbe_trb/base/tx_fifo.vhd @@ -6,6 +6,7 @@ library work; -- BUG: if no frame is stored in FIFO, and filling the FIFO triggers FIFOFULL, -- the frame must be written completely but dropped. +-- Otherwise we experience a deadlock in data transfer. -- BUG: use dynamic ALMOSTFULL to accommodate for pipelining inside the data -- multiplexer of hub. @@ -32,9 +33,7 @@ entity tx_fifo is FIFO_D_IN : in std_logic_vector(8 downto 0); -- Link stuff FRAME_START_IN : in std_logic; - LINK_ACTIVE_IN : in std_logic; - -- - DEBUG : out std_logic_vector(15 downto 0) + LINK_ACTIVE_IN : in std_logic ); end entity tx_fifo; @@ -66,6 +65,7 @@ architecture tx_fifo_arch of tx_fifo is signal mac_tx_read : std_logic; signal frame_active : std_logic; signal fifo_wr : std_logic; + signal no_frames_x : std_logic; begin @@ -99,7 +99,7 @@ begin FULL => open, ALMOSTFULL => FIFO_FULL_OUT ); - + MAC_FIFOEOF_OUT <= mac_fifoeof; mac_tx_read <= MAC_TX_READ_IN when rising_edge(CLK); @@ -130,4 +130,8 @@ begin MAC_FIFOAVAIL_OUT <= '1' when (frames_avail /= x"00") else '0'; + -- Bugfix: dropped partially stored frame, if it is the only frame and we run into FIFO full condition + no_frames_x <= '1' when (frames_avail = x"00") else '0'; + + end architecture; diff --git a/gbe_trb_ecp3/base/gbe_med_fifo.vhd b/gbe_trb_ecp3/base/gbe_med_fifo.vhd index 23afea0..5192242 100644 --- a/gbe_trb_ecp3/base/gbe_med_fifo.vhd +++ b/gbe_trb_ecp3/base/gbe_med_fifo.vhd @@ -606,9 +606,7 @@ begin FRAME_REQ_IN => FRAME_REQ_IN(i), FRAME_ACK_OUT => FRAME_ACK_OUT(i), FRAME_AVAIL_OUT => FRAME_AVAIL_OUT(i), - FRAME_START_OUT => FRAME_START_OUT(i), - -- - DEBUG => open + FRAME_START_OUT => FRAME_START_OUT(i) ); -- TX FIFO @@ -629,9 +627,7 @@ begin FIFO_D_IN => FIFO_DATA_IN((i + 1) * 9 - 1 downto i * 9), -- Link stuff FRAME_START_IN => FRAME_START_IN(i), - LINK_ACTIVE_IN => link_active(i), --an_complete(i), - -- - DEBUG => open + LINK_ACTIVE_IN => link_active(i) ); PCS_AN_READY_OUT(i) <= an_complete(i); -- needed for internal SCTRL diff --git a/gbe_trb_ecp5/media/gbe_med_fifo.vhd b/gbe_trb_ecp5/media/gbe_med_fifo.vhd index 3e1eac8..564f456 100644 --- a/gbe_trb_ecp5/media/gbe_med_fifo.vhd +++ b/gbe_trb_ecp5/media/gbe_med_fifo.vhd @@ -487,43 +487,6 @@ begin STATE_OUT => rx_bsm --open ); - -- "Good" debugging pins - debug(0) <= pll_lol; - debug(1) <= rx_cdr_lol; - debug(2) <= rx_los_low; - debug(3) <= sd_rx_cv_error(0); - debug(4) <= lsm_status; - debug(5) <= tx_pcs_rst; - debug(6) <= rx_serdes_rst; - debug(7) <= rx_pcs_rst; - debug(8) <= link_rx_ready; - debug(9) <= link_tx_ready; - debug(10) <= rx_bsm(0); --'0'; - debug(11) <= rx_bsm(1); --'0'; - debug(12) <= rx_bsm(2); --'0'; - debug(13) <= rx_bsm(3); --'0'; - debug(14) <= '0'; - debug(15) <= '0'; - debug(16) <= '0'; - debug(17) <= '0'; - debug(18) <= '0'; - debug(19) <= '0'; - -- "Bad" debugging pins - debug(20) <= RESET; - debug(21) <= CLEAR; - debug(22) <= '0'; - debug(23) <= '0'; - debug(24) <= '0'; - debug(25) <= '0'; - debug(26) <= '0'; - debug(27) <= '0'; - debug(28) <= '0'; - debug(29) <= '0'; - debug(30) <= '0'; - debug(31) <= '0'; - debug(32) <= '0'; - debug(33) <= CLK_125; - -- reset signals for RX SerDes need to be sync'ed to real RX clock for ECP5 SYNC_RST_SIGS: entity work.signal_sync generic map( WIDTH => 2 ) @@ -537,6 +500,29 @@ begin D_OUT(1) => rx_serdes_rst_q ); +-- -- "Good" debugging pins + debug(7 downto 0) <= sd_tx_data; + debug(15 downto 8) <= sd_rx_data; + debug(16) <= sd_tx_kcntl(0); + debug(17) <= sd_rx_kcntl(0); + debug(18) <= sd_tx_correct_disp(0); + debug(19) <= sd_rx_disp_error(0); + -- "Bad" debugging pins + debug(20) <= pcs_tx_en; + debug(21) <= pcs_rx_en; + debug(22) <= '0'; + debug(23) <= '0'; + debug(24) <= '0'; + debug(25) <= '0'; + debug(26) <= '0'; + debug(27) <= '0'; + debug(28) <= '0'; + debug(29) <= '0'; + debug(30) <= '0'; + debug(31) <= '0'; + debug(32) <= sd_rx_clk; + debug(33) <= CLK_125; + -- SGMII core SGMII_GBE_PCS : sgmii_gbe_core port map( @@ -724,9 +710,7 @@ begin FRAME_REQ_IN => FRAME_REQ_IN, FRAME_ACK_OUT => FRAME_ACK_OUT, FRAME_AVAIL_OUT => FRAME_AVAIL_OUT, - FRAME_START_OUT => FRAME_START_OUT, - -- - DEBUG => open + FRAME_START_OUT => FRAME_START_OUT ); -- TX FIFO @@ -747,9 +731,7 @@ begin FIFO_D_IN => FIFO_DATA_IN, -- Link stuff FRAME_START_IN => FRAME_START_IN, - LINK_ACTIVE_IN => link_active, - -- - DEBUG => open + LINK_ACTIVE_IN => link_active ); FIFO_FULL_OUT <= fifo_full_i; @@ -814,6 +796,43 @@ begin -- debug(32) <= '0'; -- debug(33) <= CLK_125; +-- -- "Good" debugging pins +-- debug(0) <= pll_lol; +-- debug(1) <= rx_cdr_lol; +-- debug(2) <= rx_los_low; +-- debug(3) <= sd_rx_cv_error(0); +-- debug(4) <= lsm_status; +-- debug(5) <= tx_pcs_rst; +-- debug(6) <= rx_serdes_rst; +-- debug(7) <= rx_pcs_rst; +-- debug(8) <= link_rx_ready; +-- debug(9) <= link_tx_ready; +-- debug(10) <= rx_bsm(0); --'0'; +-- debug(11) <= rx_bsm(1); --'0'; +-- debug(12) <= rx_bsm(2); --'0'; +-- debug(13) <= rx_bsm(3); --'0'; +-- debug(14) <= '0'; +-- debug(15) <= '0'; +-- debug(16) <= '0'; +-- debug(17) <= '0'; +-- debug(18) <= '0'; +-- debug(19) <= '0'; +-- -- "Bad" debugging pins +-- debug(20) <= RESET; +-- debug(21) <= CLEAR; +-- debug(22) <= '0'; +-- debug(23) <= '0'; +-- debug(24) <= '0'; +-- debug(25) <= '0'; +-- debug(26) <= '0'; +-- debug(27) <= '0'; +-- debug(28) <= '0'; +-- debug(29) <= '0'; +-- debug(30) <= '0'; +-- debug(31) <= '0'; +-- debug(32) <= '0'; +-- debug(33) <= CLK_125; + -- -- "Good" debugging pins -- debug(7 downto 0) <= pcs_txd; -- debug(15 downto 8) <= pcs_rxd; -- 2.43.0