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.
This commit is contained in:
Markus Koch 2025-09-23 15:59:46 +02:00
parent faa915824a
commit ac553483df

View File

@ -138,7 +138,7 @@ begin
-- CDC -- CDC
synchronizer_inst : entity work.synchronizer synchronizer_inst : entity work.synchronizer
generic map( generic map(
SIZE => 2 SIZE => 4
) )
port map( port map(
clk => clk, clk => clk,
@ -181,6 +181,7 @@ begin
signal temp_tx_data : byte; signal temp_tx_data : byte;
signal temp_tx_data_en : std_logic; signal temp_tx_data_en : std_logic;
signal temp_tx_data_ack : std_logic; signal temp_tx_data_ack : std_logic;
signal temp_tx_active : std_logic;
type state_t is (IDLE, DATA, IPG); type state_t is (IDLE, DATA, IPG);
signal state : state_t; signal state : state_t;
@ -201,8 +202,10 @@ begin
begin begin
if rst then if rst then
phy_out.tx_data_ack <= '0'; phy_out.tx_data_ack <= '0';
phy_out.tx_active <= '0';
elsif rising_edge(clk) then elsif rising_edge(clk) then
phy_out.tx_data_ack <= temp_tx_data_ack; phy_out.tx_data_ack <= temp_tx_data_ack;
phy_out.tx_active <= temp_tx_active;
end if; end if;
end process phy_out_reg; end process phy_out_reg;
@ -233,6 +236,18 @@ begin
b_rst => rst, b_rst => rst,
b_out => phy_out.tx_data_ack 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; end generate cdc_or_register;
txp : process(rmii_ref_clk, rmii_rst) is txp : process(rmii_ref_clk, rmii_rst) is
@ -255,7 +270,7 @@ begin
case state is case state is
when IDLE => when IDLE =>
sr <= temp_tx_data; sr <= temp_tx_data;
dibit_cnt <= 0; dibit_cnt <= 0;
if temp_tx_data_en then if temp_tx_data_en then
state <= DATA; state <= DATA;
@ -277,10 +292,10 @@ begin
end case; end case;
end if; end if;
end process txp; end process txp;
byte_done <= '1' when dibit_cnt = 3 else '0'; byte_done <= '1' when dibit_cnt = 3 else '0';
block_done <= '1' when (byte_cnt = 0) and (byte_done = '1') 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_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'; temp_tx_active <= '1' when state = DATA else '0';
rmii_txd <= sr(1 downto 0); rmii_txd <= sr(1 downto 0);
rmii_tx_en <= '1' when state = DATA else '0'; rmii_tx_en <= '1' when state = DATA else '0';