From ac553483dfea4191c1c5dda871d72c7e00fafa9f Mon Sep 17 00:00:00 2001 From: Markus Koch Date: Tue, 23 Sep 2025 15:59:46 +0200 Subject: [PATCH] rmii: Fix CDC for *_active On the TX side, we forgot to sync it entirely. For RX, we need to delay the rx_active signal a bit to make sure that it does not get negated before the last _valid strobe. --- trashernet/trashernet_rmii.vhd | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/trashernet/trashernet_rmii.vhd b/trashernet/trashernet_rmii.vhd index ffcff6c..6999990 100644 --- a/trashernet/trashernet_rmii.vhd +++ b/trashernet/trashernet_rmii.vhd @@ -138,7 +138,7 @@ begin -- CDC synchronizer_inst : entity work.synchronizer generic map( - SIZE => 2 + SIZE => 4 ) port map( clk => clk, @@ -181,6 +181,7 @@ begin signal temp_tx_data : byte; signal temp_tx_data_en : std_logic; signal temp_tx_data_ack : std_logic; + signal temp_tx_active : std_logic; type state_t is (IDLE, DATA, IPG); signal state : state_t; @@ -201,8 +202,10 @@ begin begin if rst then phy_out.tx_data_ack <= '0'; + phy_out.tx_active <= '0'; elsif rising_edge(clk) then phy_out.tx_data_ack <= temp_tx_data_ack; + phy_out.tx_active <= temp_tx_active; end if; end process phy_out_reg; @@ -233,6 +236,18 @@ begin b_rst => rst, b_out => phy_out.tx_data_ack ); + + synchronizer_inst : entity work.synchronizer + generic map( + SIZE => 2 + ) + port map( + clk => clk, + rst => rst, + data_in => temp_tx_active, + data_out => phy_out.tx_active + ); + end generate cdc_or_register; txp : process(rmii_ref_clk, rmii_rst) is @@ -255,7 +270,7 @@ begin case state is when IDLE => - sr <= temp_tx_data; + sr <= temp_tx_data; dibit_cnt <= 0; if temp_tx_data_en then state <= DATA; @@ -277,10 +292,10 @@ begin end case; end if; end process txp; - byte_done <= '1' when dibit_cnt = 3 else '0'; - block_done <= '1' when (byte_cnt = 0) and (byte_done = '1') else '0'; - temp_tx_data_ack <= '1' when (state = DATA) and (byte_done = '1') and (temp_tx_data_en = '1') else '0'; - phy_out.tx_active <= '1' when state = DATA else '0'; + byte_done <= '1' when dibit_cnt = 3 else '0'; + block_done <= '1' when (byte_cnt = 0) and (byte_done = '1') else '0'; + temp_tx_data_ack <= '1' when (state = DATA) and (byte_done = '1') and (temp_tx_data_en = '1') else '0'; + temp_tx_active <= '1' when state = DATA else '0'; rmii_txd <= sr(1 downto 0); rmii_tx_en <= '1' when state = DATA else '0';