diff --git a/trashernet/trashernet_phy.vhd b/trashernet/trashernet_phy.vhd index ab76eea..694c261 100644 --- a/trashernet/trashernet_phy.vhd +++ b/trashernet/trashernet_phy.vhd @@ -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,8 +271,10 @@ 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 - nlp_timeout_cnt <= nlp_timeout_cnt - 1; + 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; @@ -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...