Compare commits

..

1 Commits

Author SHA1 Message Date
3d530f6625 eth+ipv4prot: Fix protocol arbitration
Fixes #13.
2023-01-15 10:43:00 +01:00
5 changed files with 23 additions and 41 deletions

View File

@ -28,14 +28,6 @@ Notes:
* The RX pull up/downs are probably not the best idea, and fixable in a better way. But for now, this shall work -- and suffice!
* On the TX side, I'm grossly overloading the drivers. A line driver would probably be a good idea. Or you can just parallel multiple outputs ;D
## Stats
Sythesized for a Lattice LFXP2-5E FPGA using LSE / Diamond v3.12:
| Configuration | Slices | LUT4 | Registers |
| ---------------- | ------ | ---- | --------- |
| `trashernet_phy` | 115 | 188 | 91 |
## License
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.

View File

@ -141,7 +141,10 @@ begin
end if;
when TXD =>
state <= IDLE when (not mac_in.tx_mac_data_en or not mac_out.tx_active);
if (not mac_in.tx_mac_data_en or not mac_out.tx_active) then
state <= IDLE;
sel <= SEL_ETH_I; -- To avoid arbitration errors, always select the highest priority one by default
end if;
end case;
end if;
end process arb;

View File

@ -105,7 +105,10 @@ begin
end loop;
when TXD =>
state <= IDLE when (not ipv4_in.tx_en);
if not ipv4_in.tx_en then
state <= IDLE;
tx_sel <= ipv4_protocol_in'left; -- To avoid arbitration errors, always select the highest priority one by default
end if;
end case;
end if;
end process arb;

View File

@ -253,7 +253,6 @@ begin
begin
if rst then
phy_out.rx_data_valid <= '0';
phy_out.rx_data <= (others => '0'); -- Needed for yosys to compile
elsif rising_edge(clk) then
phy_out.rx_data_valid <= '0';
@ -297,10 +296,7 @@ begin
-- -------------------------------------------------------------------------
transmitter : block
constant TX_STB_CNT_IDEAL : real := real(F_CLK) / real((F_ETH * 2));
constant TX_STB_SKIP_ERROR : real := abs (round(TX_STB_CNT_IDEAL) - TX_STB_CNT_IDEAL);
constant TX_STB_CNT_MAX : integer := integer(round(TX_STB_CNT_IDEAL + 0.25)) - 1; -- Round up starting for error > 0.25
constant TX_STB_SKIP_SECOND : boolean := TX_STB_SKIP_ERROR >= 0.25; -- Skip one clock cycle every other symbol to hit clock rate in between when the divider is close to x.5
constant TX_STB_CNT_MAX : integer := integer(round(real(F_CLK) / real((F_ETH * 2)))) - 1;
signal tx_stb_cnt : integer range 0 to TX_STB_CNT_MAX;
type tx_state_t is (IDLE, NLP, TX, IPG);
@ -371,9 +367,6 @@ begin
if tx_stb_cnt = 0 then
tx_stb_cnt <= TX_STB_CNT_MAX;
if TX_STB_SKIP_SECOND and bit_stage = '1' then
tx_stb_cnt <= TX_STB_CNT_MAX - 1;
end if;
else
tx_stb_cnt <= tx_stb_cnt - 1;
end if;

View File

@ -44,14 +44,14 @@ architecture rtl of trashernet_phy_cdc is
signal phy_phy_in : phy_in_t;
-- Helper signals
signal rx_data_i : byte;
signal rx_data_valid_i : std_logic;
begin
assert F_CLK_PHY > 2 * F_CLK report "F_CLK_PHY must be at least 2x F_CLK" severity failure;
-- -------------------------------------------------------------------------
-- Drives: PHY clock domain
-- -------------------------------------------------------------------------
-- Reset synchronizer for PHY
rstsync : process(phy_clk, rst) is
begin
if rst then
@ -61,7 +61,6 @@ begin
end if;
end process rstsync;
-- Operate Trashernet in PHY clock domain
trashernet_phy_inst : entity work.trashernet_phy
generic map(
F_CLK => F_CLK_PHY
@ -76,22 +75,6 @@ begin
tx_n => tx_n
);
-- Latch data in PHY clock domain when valid is strobed
-- If the other clock domain is slower than the time it takes for the strobe to synchronize,
-- `phy_phy_out.rx_data` will already have shifted in the next bit and no longer be valid.
-- Therefore, we need to latch it here.
rxdff : process(phy_clk, rst) is
begin
if rst then
rx_data_i <= (others => '0');
elsif rising_edge(phy_clk) then
if phy_phy_out.rx_data_valid then
rx_data_i <= phy_phy_out.rx_data;
end if;
end if;
end process rxdff;
synchronizer_txen_inst : entity work.synchronizer
generic map(
SIZE => 5
@ -115,10 +98,18 @@ begin
a_in => phy_phy_out.rx_data_valid,
b_clk => clk,
b_rst => rst,
b_out => phy_out.rx_data_valid
b_out => rx_data_valid_i
);
phy_out.rx_data <= rx_data_i; -- No need to synchronize in new clock domain as latched data has been stable for a while thanks to the delay in the _valid synchronizer
rxdvff : process(clk, rst) is
begin
if rst then
phy_out.rx_data_valid <= '0';
elsif rising_edge(clk) then
phy_out.rx_data_valid <= rx_data_valid_i;
phy_out.rx_data <= phy_phy_out.rx_data; -- Data should be stable after the time it takes the _valid signal to go through the synchronizer
end if;
end process rxdvff;
cdc_strobe_rxer_inst : entity work.cdc_strobe
port map(