phy: Fix NLPs
We need a different NLP timeout for RX than TX. Also use a prescaler to improve timing.
This commit is contained in:
parent
a9039a175c
commit
075f935e12
@ -39,8 +39,31 @@ end entity trashernet_phy;
|
||||
architecture rtl of trashernet_phy is
|
||||
constant F_ETH : integer := 10000000;
|
||||
|
||||
signal tick_ms : std_logic; -- 1 ms tick (for NLP)
|
||||
begin
|
||||
|
||||
common : block
|
||||
constant TICK_MS_CNT_MAX : integer := (F_CLK / 1000) - 1;
|
||||
signal tick_ms_count : integer range 0 to TICK_MS_CNT_MAX;
|
||||
begin
|
||||
mstick : process(clk, rst) is
|
||||
begin
|
||||
if rst then
|
||||
tick_ms_count <= TICK_MS_CNT_MAX;
|
||||
tick_ms <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
tick_ms <= '0';
|
||||
if tick_ms_count = 0 then
|
||||
tick_ms <= '1';
|
||||
tick_ms_count <= TICK_MS_CNT_MAX;
|
||||
else
|
||||
tick_ms_count <= tick_ms_count - 1;
|
||||
end if;
|
||||
end if;
|
||||
end process mstick;
|
||||
|
||||
end block common;
|
||||
|
||||
receiver : block
|
||||
-- Signal conditioning
|
||||
signal rx : std_logic;
|
||||
@ -56,7 +79,7 @@ begin
|
||||
signal bit_cnt : integer range 0 to 7;
|
||||
|
||||
-- NLP supervision
|
||||
constant NLP_TIMEOUT_CNT_MAX : integer := integer(round(real(F_CLK) * 16.0 * 10.0 ** (-3))) - 1; -- Every 16 ms
|
||||
constant NLP_TIMEOUT_CNT_MAX : integer := (16 + 8) - 1; -- Every 16 ms (timebase 1 ms)
|
||||
signal nlp_timeout_cnt : integer range 0 to NLP_TIMEOUT_CNT_MAX;
|
||||
begin
|
||||
-- Synchronize RX input
|
||||
@ -248,11 +271,13 @@ begin
|
||||
if rx_edge then -- Technically, we should use only the rising edge here, but a project called `trashernet` probably won't mind ;)
|
||||
nlp_timeout_cnt <= NLP_TIMEOUT_CNT_MAX;
|
||||
else
|
||||
if (nlp_timeout_cnt /= 0) then
|
||||
if tick_ms then
|
||||
if nlp_timeout_cnt /= 0 then
|
||||
nlp_timeout_cnt <= nlp_timeout_cnt - 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process nlp_timeout_p;
|
||||
phy_out.carrier_detect <= '1' when nlp_timeout_cnt /= 0 else '0';
|
||||
end block receiver;
|
||||
@ -268,10 +293,11 @@ begin
|
||||
signal sr : std_logic_vector(phy_in.tx_data'range);
|
||||
signal bit_stage : std_logic;
|
||||
|
||||
constant BIT_CNT_MAX_NLP : integer := 16000000 / 100; -- 16 ms (timebase 100 ns)
|
||||
constant BIT_CNT_MAX_IPG : integer := 96;
|
||||
constant BIT_CNT_MAX_DATA : integer := sr'length - 1;
|
||||
signal bit_cnt : integer range 0 to maximum(maximum(BIT_CNT_MAX_NLP, BIT_CNT_MAX_DATA), BIT_CNT_MAX_IPG);
|
||||
signal bit_cnt : integer range 0 to maximum(BIT_CNT_MAX_IPG, BIT_CNT_MAX_DATA);
|
||||
constant NLP_CNT_MAX : integer := 15; -- specced 16 ms, but there's margin, so let's choose 15 to save a bit (timebase 1 ms)
|
||||
signal nlp_cnt : integer range 0 to NLP_CNT_MAX;
|
||||
|
||||
type tx_mode_t is (OFF, NLP, ACTIVE);
|
||||
signal tx_mode : tx_mode_t;
|
||||
@ -308,7 +334,7 @@ begin
|
||||
tx_state <= IDLE;
|
||||
tx_mode <= OFF;
|
||||
|
||||
bit_cnt <= BIT_CNT_MAX_NLP;
|
||||
nlp_cnt <= NLP_CNT_MAX;
|
||||
bit_stage <= '0';
|
||||
end procedure go_idle;
|
||||
|
||||
@ -343,7 +369,11 @@ begin
|
||||
bit_cnt <= bit_cnt - 1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if tick_ms then
|
||||
if (nlp_cnt /= 0) then
|
||||
nlp_cnt <= nlp_cnt - 1;
|
||||
end if;
|
||||
end if;
|
||||
case tx_state is
|
||||
when IDLE =>
|
||||
if phy_in.tx_data_en then -- New packet to TX
|
||||
@ -352,7 +382,7 @@ begin
|
||||
bit_stage <= '1';
|
||||
tx_stb_cnt <= TX_STB_CNT_MAX; -- resync
|
||||
|
||||
elsif bit_cnt = 0 then -- NLP timeout
|
||||
elsif nlp_cnt = 0 then -- NLP timeout
|
||||
transmit_nlp;
|
||||
|
||||
--bit_cnt <= 1; Let's save some resources here...
|
||||
|
Loading…
Reference in New Issue
Block a user