phy: Refactor to use records for the application interface

This commit is contained in:
Markus Koch 2021-09-25 12:28:04 +02:00
parent cf6fb61195
commit cfac94136a
6 changed files with 152 additions and 209 deletions

View File

@ -22,22 +22,15 @@ entity bench_trashernet_mac is
end entity bench_trashernet_mac; end entity bench_trashernet_mac;
architecture bench of bench_trashernet_mac is architecture bench of bench_trashernet_mac is
signal clk : std_logic; signal clk : std_logic;
signal phy_clk : std_logic; signal phy_clk : std_logic;
signal rst : std_logic; signal rst : std_logic;
signal rx_data : std_logic_vector(7 downto 0);
signal rx_data_valid : std_logic; signal phy_out : phy_out_t;
signal rx_active : std_logic; signal phy_in : phy_in_t;
signal tx_data : std_logic_vector(7 downto 0); signal rx_p : std_logic;
signal tx_data_en : std_logic; signal tx_p : std_logic;
signal tx_data_ack : std_logic; signal tx_n : std_logic;
signal tx_active : std_logic;
signal tx_header : mac_header_fields;
signal carrier_detect : std_logic;
signal rx_error : std_logic;
signal rx_p : std_logic;
signal tx_p : std_logic;
signal tx_n : std_logic;
signal rx_mac_data : byte; signal rx_mac_data : byte;
signal rx_mac_valid : std_logic; signal rx_mac_valid : std_logic;
@ -48,6 +41,7 @@ architecture bench of bench_trashernet_mac is
signal tx_mac_data_en : std_logic; signal tx_mac_data_en : std_logic;
signal tx_mac_data_ack : std_logic; signal tx_mac_data_ack : std_logic;
signal rx_header : mac_header_fields; signal rx_header : mac_header_fields;
signal tx_header : mac_header_fields;
constant TEST_BENCH_LOOPBACK : boolean := true; constant TEST_BENCH_LOOPBACK : boolean := true;
@ -58,40 +52,26 @@ begin
F_CLK_PHY => 100000000 F_CLK_PHY => 100000000
) )
port map( port map(
clk => clk, clk => clk,
phy_clk => phy_clk, phy_clk => phy_clk,
rst => rst, rst => rst,
rx_data => rx_data, phy_out => phy_out,
rx_data_valid => rx_data_valid, phy_in => phy_in,
rx_active => rx_active, rx_p => rx_p,
tx_data => tx_data, tx_p => tx_p,
tx_data_en => tx_data_en, tx_n => tx_n
tx_data_ack => tx_data_ack,
tx_active => tx_active,
carrier_detect => carrier_detect,
rx_error => rx_error,
rx_p => rx_p,
tx_p => tx_p,
tx_n => tx_n
); );
trashernet_mac_inst : entity trashernet.trashernet_mac trashernet_mac_inst : entity trashernet.trashernet_mac
port map( port map(
clk => clk, clk => clk,
rst => rst, rst => rst,
rx_data => rx_data, phy_out => phy_out,
rx_data_valid => rx_data_valid, phy_in => phy_in,
rx_active => rx_active,
tx_data => tx_data,
tx_data_en => tx_data_en,
tx_data_ack => tx_data_ack,
tx_active => tx_active,
carrier_detect => carrier_detect,
rx_error => rx_error,
rx_header => rx_header, rx_header => rx_header,
rx_mac_header_rcv => rx_mac_header_rcv,
rx_mac_data => rx_mac_data, rx_mac_data => rx_mac_data,
rx_mac_valid => rx_mac_valid, rx_mac_valid => rx_mac_valid,
rx_mac_header_rcv => rx_mac_header_rcv,
rx_mac_crc_ok => rx_mac_crc_ok, rx_mac_crc_ok => rx_mac_crc_ok,
rx_mac_crc_error => rx_mac_crc_error, rx_mac_crc_error => rx_mac_crc_error,
tx_header => tx_header, tx_header => tx_header,
@ -164,8 +144,8 @@ begin
receiver : process is receiver : process is
begin begin
wait until rising_edge(clk); wait until rising_edge(clk);
if rx_data_valid then if phy_out.rx_data_valid then
report "[PHY] RX byte: " & to_hstring(rx_data); report "[PHY] RX byte: " & to_hstring(phy_out.rx_data);
end if; end if;
if rx_mac_valid then if rx_mac_valid then
report "[MAC] RX byte: " & to_hstring(rx_mac_data); report "[MAC] RX byte: " & to_hstring(rx_mac_data);

View File

@ -25,18 +25,12 @@ architecture bench of bench_trashernet_phy is
signal clk : std_logic; signal clk : std_logic;
signal phy_clk : std_logic; signal phy_clk : std_logic;
signal rst : std_logic; signal rst : std_logic;
signal rx_data : std_logic_vector(7 downto 0); signal phy_out : phy_out_t;
signal rx_data_valid : std_logic; signal phy_in : phy_in_t;
signal rx_active : std_logic; signal rx_p : std_logic;
signal tx_data : std_logic_vector(7 downto 0); signal tx_p : std_logic;
signal tx_data_en : std_logic; signal tx_n : std_logic;
signal tx_data_ack : std_logic;
signal carrier_detect : std_logic;
signal rx_error : std_logic;
signal rx_p : std_logic;
signal tx_p : std_logic;
signal tx_active : std_logic;
signal tx_n : std_logic;
begin begin
trashernet_phy_cdc_inst : entity trashernet.trashernet_phy_cdc trashernet_phy_cdc_inst : entity trashernet.trashernet_phy_cdc
@ -45,21 +39,14 @@ begin
F_CLK_PHY => 100000000 F_CLK_PHY => 100000000
) )
port map( port map(
clk => clk, clk => clk,
phy_clk => phy_clk, phy_clk => phy_clk,
rst => rst, rst => rst,
rx_data => rx_data, phy_out => phy_out,
rx_data_valid => rx_data_valid, phy_in => phy_in,
rx_active => rx_active, rx_p => rx_p,
tx_data => tx_data, tx_p => tx_p,
tx_data_en => tx_data_en, tx_n => tx_n
tx_data_ack => tx_data_ack,
tx_active => tx_active,
carrier_detect => carrier_detect,
rx_error => rx_error,
rx_p => rx_p,
tx_p => tx_p,
tx_n => tx_n
); );
clock_driver : process clock_driver : process
@ -96,8 +83,8 @@ begin
receiver : process is receiver : process is
begin begin
wait until rising_edge(clk); wait until rising_edge(clk);
if rx_data_valid then if phy_out.rx_data_valid then
report "RX byte: " & to_hstring(rx_data); report "RX byte: " & to_hstring(phy_out.rx_data);
end if; end if;
end process receiver; end process receiver;

View File

@ -22,17 +22,8 @@ entity trashernet_mac is
rst : in std_logic; -- Asynchronous reset rst : in std_logic; -- Asynchronous reset
-- PHY signals -- PHY signals
rx_data : in byte; -- RX Data phy_out : in phy_out_t; -- PHY application IF (out of PHY)
rx_data_valid : in std_logic; -- RX Data valid phy_in : out phy_in_t; -- PHY application IF (into PHY)
rx_active : in std_logic; -- RX of packet in progress
tx_data : out byte; -- TX Data
tx_data_en : out std_logic; -- Transmitter enable
tx_data_ack : in std_logic; -- Latched data_tx
tx_active : in std_logic; -- Transmitter active
carrier_detect : in std_logic; -- Carrier detected
rx_error : in std_logic; -- Receive error
-- MAC signals -- MAC signals
rx_header : out mac_header_fields; -- RX MAC Header Data rx_header : out mac_header_fields; -- RX MAC Header Data
@ -79,8 +70,8 @@ begin
port map( port map(
clk => clk, clk => clk,
rst => rst, rst => rst,
data => rx_data, data => phy_out.rx_data,
data_valid => rx_data_valid, data_valid => phy_out.rx_data_valid,
crc_clear => crc_clear, crc_clear => crc_clear,
crc_out => crc crc_out => crc
); );
@ -106,8 +97,8 @@ begin
case state is case state is
when HEAD => when HEAD =>
if rx_data_valid then if phy_out.rx_data_valid then
sr_head <= sr_head(sr_head'low + 1 to sr_head'high) & rx_data; sr_head <= sr_head(sr_head'low + 1 to sr_head'high) & phy_out.rx_data;
if byte_count = (HEAD_LENGTH - 1) then if byte_count = (HEAD_LENGTH - 1) then
state <= PAYLOAD; state <= PAYLOAD;
byte_count <= 0; byte_count <= 0;
@ -119,24 +110,24 @@ begin
end if; end if;
end if; end if;
when PAYLOAD => when PAYLOAD =>
if rx_data_valid then if phy_out.rx_data_valid then
sr_payload <= sr_payload(sr_payload'low + 1 to sr_payload'high) & rx_data; sr_payload <= sr_payload(sr_payload'low + 1 to sr_payload'high) & phy_out.rx_data;
if byte_count = CRC_LENGTH then if byte_count = CRC_LENGTH then
rx_mac_valid <= '1'; rx_mac_valid <= '1';
else else
byte_count <= byte_count + 1; byte_count <= byte_count + 1;
end if; end if;
end if; end if;
if not rx_active then if not phy_out.rx_active then
rx_mac_crc_ok <= crc_ok; rx_mac_crc_ok <= crc_ok;
rx_mac_crc_error <= not crc_ok; rx_mac_crc_error <= not crc_ok;
end if; end if;
if rx_error then if phy_out.rx_error then
rx_mac_crc_error <= '1'; rx_mac_crc_error <= '1';
end if; end if;
end case; end case;
if (not rx_active) or rx_error then if (not phy_out.rx_active) or phy_out.rx_error then
byte_count <= 0; byte_count <= 0;
state <= HEAD; state <= HEAD;
crc_clear <= '1'; crc_clear <= '1';
@ -173,7 +164,7 @@ begin
port map( port map(
clk => clk, clk => clk,
rst => rst, rst => rst,
data => tx_data, data => phy_in.tx_data,
data_valid => crc_valid, data_valid => crc_valid,
crc_clear => crc_clear, crc_clear => crc_clear,
crc_out => crc crc_out => crc
@ -188,7 +179,7 @@ begin
tx_mac_data_ack <= '0'; tx_mac_data_ack <= '0';
crc_valid <= '0'; crc_valid <= '0';
if tx_data_ack then if phy_out.tx_data_ack then
sr <= sr(sr'low + 1 to sr'high) & x"00"; sr <= sr(sr'low + 1 to sr'high) & x"00";
crc_valid <= '1'; crc_valid <= '1';
if byte_cnt /= 0 then if byte_cnt /= 0 then
@ -197,14 +188,14 @@ begin
end if; end if;
case tx_state is case tx_state is
when IDLE => when IDLE =>
if not tx_active and tx_mac_data_en then if not phy_out.tx_active and tx_mac_data_en then
sr(0 to 7) <= byte_vector'(0 to 6 => x"55", 7 => x"D5"); sr(0 to 7) <= byte_vector'(0 to 6 => x"55", 7 => x"D5");
byte_cnt <= 7; byte_cnt <= 7;
tx_state <= HEADER; tx_state <= HEADER;
end if; end if;
when HEADER => when HEADER =>
if (tx_data_ack = '1') and (byte_cnt = 0) then -- Sync Header TX complete if (phy_out.tx_data_ack = '1') and (byte_cnt = 0) then -- Sync Header TX complete
sr <= tx_header.mac_destination & tx_header.mac_source & tx_header.mac_ethertype; sr <= tx_header.mac_destination & tx_header.mac_source & tx_header.mac_ethertype;
crc_valid <= '1'; crc_valid <= '1';
byte_cnt <= BIT_CNT_MAX; byte_cnt <= BIT_CNT_MAX;
@ -212,7 +203,7 @@ begin
end if; end if;
when DATA => when DATA =>
if (tx_data_ack = '1') and (byte_cnt = 0) then -- MAC Header TX complete if (phy_out.tx_data_ack = '1') and (byte_cnt = 0) then -- MAC Header TX complete
if tx_mac_data_en then if tx_mac_data_en then
sr(0) <= tx_mac_data; sr(0) <= tx_mac_data;
tx_mac_data_ack <= '1'; tx_mac_data_ack <= '1';
@ -224,15 +215,15 @@ begin
end if; end if;
when TXCRC => when TXCRC =>
if (tx_data_ack = '1') and (byte_cnt = 0) then -- CRC TX complete if (phy_out.tx_data_ack = '1') and (byte_cnt = 0) then -- CRC TX complete
tx_state <= IDLE; tx_state <= IDLE;
end if; end if;
end case; end case;
end if; end if;
end process tx_main; end process tx_main;
tx_data_en <= '1' when tx_state /= IDLE else '0'; phy_in.tx_data_en <= '1' when tx_state /= IDLE else '0';
crc_clear <= '1' when tx_state = HEADER else '0'; crc_clear <= '1' when tx_state = HEADER else '0';
tx_data <= sr(sr'low); phy_in.tx_data <= sr(sr'low);
end block tx; end block tx;
end architecture rtl; end architecture rtl;

View File

@ -22,26 +22,17 @@ entity trashernet_phy is
); );
port( port(
-- Global -- Global
clk : in std_logic; -- Global clock clk : in std_logic; -- Global clock
rst : in std_logic; -- Asynchronous reset rst : in std_logic; -- Asynchronous reset
-- Eth -- PHY application interface
rx_data : out byte; -- RX Data phy_out : out phy_out_t; -- PHY application IF (out)
rx_data_valid : out std_logic; -- RX Data valid phy_in : in phy_in_t; -- PHY application IF (in)
rx_active : out std_logic; -- RX of packet in progress
tx_data : in byte; -- TX Data
tx_data_en : in std_logic; -- Transmitter enable
tx_data_ack : out std_logic; -- Latched data_tx
tx_active : out std_logic; -- Transmission in progress
carrier_detect : out std_logic; -- Carrier detected
rx_error : out std_logic; -- Receive error
-- Ethernet physical signals -- Ethernet physical signals
rx_p : in std_logic; rx_p : in std_logic;
tx_p : out std_logic; tx_p : out std_logic;
tx_n : out std_logic tx_n : out std_logic
); );
end entity trashernet_phy; end entity trashernet_phy;
@ -69,7 +60,7 @@ begin
signal nlp_timeout_cnt : integer range 0 to NLP_TIMEOUT_CNT_MAX; signal nlp_timeout_cnt : integer range 0 to NLP_TIMEOUT_CNT_MAX;
begin begin
-- Synchronize RX input -- Synchronize RX input
synchronizer_inst : entity work.synchronizer synchronizer_rxp_inst : entity work.synchronizer
port map( port map(
clk => clk, clk => clk,
rst => rst, rst => rst,
@ -188,11 +179,11 @@ begin
if rst then if rst then
demanchestization_state <= SYNC; demanchestization_state <= SYNC;
bit_stb <= '0'; bit_stb <= '0';
rx_active <= '0'; phy_out.rx_active <= '0';
rx_error <= '0'; phy_out.rx_error <= '0';
elsif rising_edge(clk) then elsif rising_edge(clk) then
bit_stb <= '0'; bit_stb <= '0';
rx_error <= '0'; phy_out.rx_error <= '0';
if (bit_ev /= NONE) then if (bit_ev /= NONE) then
case demanchestization_state is case demanchestization_state is
@ -200,7 +191,7 @@ begin
if (bit_ev = KEEP) then if (bit_ev = KEEP) then
bit_value <= '1'; bit_value <= '1';
demanchestization_state <= DATA; demanchestization_state <= DATA;
rx_active <= '1'; phy_out.rx_active <= '1';
end if; end if;
when DATA => -- @suppress: Condition outside of case allows to exit this state when DATA => -- @suppress: Condition outside of case allows to exit this state
bit_value <= not bit_value when bit_ev = TOGGLE else bit_value; bit_value <= not bit_value when bit_ev = TOGGLE else bit_value;
@ -211,13 +202,13 @@ begin
end if; end if;
if (bit_ev = ERROR) then if (bit_ev = ERROR) then
rx_error <= '1'; phy_out.rx_error <= '1';
demanchestization_state <= ERROR; demanchestization_state <= ERROR;
end if; end if;
if (not transition_activity) then if (not transition_activity) then
demanchestization_state <= SYNC; demanchestization_state <= SYNC;
rx_active <= '0'; phy_out.rx_active <= '0';
end if; end if;
end if; end if;
end process bit_recovery; end process bit_recovery;
@ -227,17 +218,17 @@ begin
bytizer : process(clk, rst) is bytizer : process(clk, rst) is
begin begin
if rst then if rst then
rx_data_valid <= '0'; phy_out.rx_data_valid <= '0';
elsif rising_edge(clk) then elsif rising_edge(clk) then
rx_data_valid <= '0'; phy_out.rx_data_valid <= '0';
if rx_active then if phy_out.rx_active then
if (bit_stb) then if (bit_stb) then
rx_data <= bit_value & rx_data(rx_data'high downto rx_data'low + 1); phy_out.rx_data <= bit_value & phy_out.rx_data(phy_out.rx_data'high downto phy_out.rx_data'low + 1);
if (bit_cnt = 7) then if (bit_cnt = 7) then
rx_data_valid <= '1'; phy_out.rx_data_valid <= '1';
bit_cnt <= 0; bit_cnt <= 0;
else else
bit_cnt <= bit_cnt + 1; bit_cnt <= bit_cnt + 1;
end if; end if;
@ -263,7 +254,7 @@ begin
end if; end if;
end if; end if;
end process nlp_timeout_p; end process nlp_timeout_p;
carrier_detect <= '1' when nlp_timeout_cnt /= 0 else '0'; phy_out.carrier_detect <= '1' when nlp_timeout_cnt /= 0 else '0';
end block receiver; end block receiver;
-- ------------------------------------------------------------------------- -- -------------------------------------------------------------------------
@ -274,7 +265,7 @@ begin
type tx_state_t is (IDLE, NLP, TX, IPG); type tx_state_t is (IDLE, NLP, TX, IPG);
signal tx_state : tx_state_t; signal tx_state : tx_state_t;
signal sr : std_logic_vector(tx_data'range); signal sr : std_logic_vector(phy_in.tx_data'range);
signal bit_stage : std_logic; signal bit_stage : std_logic;
constant BIT_CNT_MAX_NLP : integer := 16000 / 100; -- 16 ms (timebase 100 ns) constant BIT_CNT_MAX_NLP : integer := 16000 / 100; -- 16 ms (timebase 100 ns)
@ -291,10 +282,10 @@ begin
tx_state <= TX; tx_state <= TX;
tx_mode <= ACTIVE; tx_mode <= ACTIVE;
sr <= tx_data; sr <= phy_in.tx_data;
bit_stage <= '0'; bit_stage <= '0';
bit_cnt <= BIT_CNT_MAX_DATA; bit_cnt <= BIT_CNT_MAX_DATA;
tx_data_ack <= '1'; phy_out.tx_data_ack <= '1';
end procedure transmit_byte; end procedure transmit_byte;
procedure transmit_ipg is procedure transmit_ipg is
@ -325,13 +316,13 @@ begin
begin begin
if rst then if rst then
tx_data_ack <= '0'; phy_out.tx_data_ack <= '0';
tx_stb_cnt <= TX_STB_CNT_MAX; tx_stb_cnt <= TX_STB_CNT_MAX;
tx_mode <= OFF; tx_mode <= OFF;
go_idle; go_idle;
elsif rising_edge(clk) then elsif rising_edge(clk) then
tx_data_ack <= '0'; phy_out.tx_data_ack <= '0';
if tx_stb_cnt = 0 then if tx_stb_cnt = 0 then
tx_stb_cnt <= TX_STB_CNT_MAX; tx_stb_cnt <= TX_STB_CNT_MAX;
@ -351,7 +342,7 @@ begin
case tx_state is case tx_state is
when IDLE => when IDLE =>
if tx_data_en then -- New packet to TX if phy_in.tx_data_en then -- New packet to TX
transmit_byte; transmit_byte;
bit_stage <= '1'; bit_stage <= '1';
tx_stb_cnt <= TX_STB_CNT_MAX; -- resync tx_stb_cnt <= TX_STB_CNT_MAX; -- resync
@ -372,7 +363,7 @@ begin
if (bit_stage = '1') then if (bit_stage = '1') then
sr <= '0' & sr(sr'high downto sr'low + 1); sr <= '0' & sr(sr'high downto sr'low + 1);
if bit_cnt = 0 then if bit_cnt = 0 then
if tx_data_en then if phy_in.tx_data_en then
transmit_byte; transmit_byte;
else else
transmit_ipg; transmit_ipg;
@ -387,7 +378,7 @@ begin
end case; end case;
end if; end if;
end process tx_main; end process tx_main;
tx_active <= '1' when tx_state /= IDLE else '0'; phy_out.tx_active <= '1' when tx_state /= IDLE else '0';
driver : process(clk, rst) is driver : process(clk, rst) is
begin begin

View File

@ -22,42 +22,26 @@ entity trashernet_phy_cdc is
); );
port( port(
-- Global -- Global
clk : in std_logic; -- Clock for internal interface clk : in std_logic; -- Clock for internal interface
phy_clk : in std_logic; -- Clock for PHY (rx_p, tx_p) phy_clk : in std_logic; -- Clock for PHY (rx_p, tx_p)
rst : in std_logic; -- Asynchronous reset rst : in std_logic; -- Asynchronous reset
-- System interface -- PHY application interface
rx_data : out byte; -- RX Data phy_out : out phy_out_t; -- PHY application IF (out)
rx_data_valid : out std_logic; -- RX Data valid phy_in : in phy_in_t; -- PHY application IF (in)
rx_active : out std_logic; -- RX of packet in progress
tx_data : in byte; -- TX Data
tx_data_en : in std_logic; -- Transmitter enable
tx_data_ack : out std_logic; -- Latched data_tx
tx_active : out std_logic; -- Transmission in progress
carrier_detect : out std_logic; -- Carrier detected
rx_error : out std_logic; -- Receive error
-- Ethernet physical signals -- Ethernet physical signals
rx_p : in std_logic; rx_p : in std_logic;
tx_p : out std_logic; tx_p : out std_logic;
tx_n : out std_logic tx_n : out std_logic
); );
end entity trashernet_phy_cdc; end entity trashernet_phy_cdc;
architecture RTL of trashernet_phy_cdc is architecture rtl of trashernet_phy_cdc is
-- PHY signals -- PHY signals
signal phy_rst : std_logic; signal phy_rst : std_logic;
signal phy_rx_data : std_logic_vector(7 downto 0); signal phy_phy_out : phy_out_t;
signal phy_rx_data_valid : std_logic; signal phy_phy_in : phy_in_t;
signal phy_rx_active : std_logic;
signal phy_tx_data : std_logic_vector(7 downto 0);
signal phy_tx_data_en : std_logic;
signal phy_tx_data_ack : std_logic;
signal phy_carrier_detect : std_logic;
signal phy_rx_error : std_logic;
signal phy_tx_active : std_logic;
-- Helper signals -- Helper signals
signal rx_data_valid_i : std_logic; signal rx_data_valid_i : std_logic;
@ -80,20 +64,13 @@ begin
F_CLK => F_CLK_PHY F_CLK => F_CLK_PHY
) )
port map( port map(
clk => phy_clk, clk => phy_clk,
rst => phy_rst, rst => phy_rst,
rx_data => phy_rx_data, phy_out => phy_phy_out,
rx_data_valid => phy_rx_data_valid, phy_in => phy_phy_in,
rx_active => phy_rx_active, rx_p => rx_p,
tx_data => phy_tx_data, tx_p => tx_p,
tx_data_en => phy_tx_data_en, tx_n => tx_n
tx_data_ack => phy_tx_data_ack,
tx_active => phy_tx_active,
carrier_detect => phy_carrier_detect,
rx_error => phy_rx_error,
rx_p => rx_p,
tx_p => tx_p,
tx_n => tx_n
); );
synchronizer_txen_inst : entity work.synchronizer synchronizer_txen_inst : entity work.synchronizer
@ -103,11 +80,11 @@ begin
port map( port map(
clk => phy_clk, clk => phy_clk,
rst => phy_rst, rst => phy_rst,
data_in => tx_data_en, data_in => phy_in.tx_data_en,
data_out => phy_tx_data_en data_out => phy_phy_in.tx_data_en
); );
phy_tx_data <= tx_data; -- When tx_data_en is through the synchronizer, this should be stable (and in the other direction, it should only change when we don't read it anyways) phy_phy_in.tx_data <= phy_in.tx_data; -- When tx_data_en is through the synchronizer, this should be stable (and in the other direction, it should only change when we don't read it anyways)
-- ------------------------------------------------------------------------- -- -------------------------------------------------------------------------
-- Drives: System clock domain -- Drives: System clock domain
@ -116,7 +93,7 @@ begin
port map( port map(
a_clk => phy_clk, a_clk => phy_clk,
a_rst => phy_rst, a_rst => phy_rst,
a_in => phy_rx_data_valid, a_in => phy_phy_out.rx_data_valid,
b_clk => clk, b_clk => clk,
b_rst => rst, b_rst => rst,
b_out => rx_data_valid_i b_out => rx_data_valid_i
@ -125,10 +102,10 @@ begin
rxdvff : process(clk, rst) is rxdvff : process(clk, rst) is
begin begin
if rst then if rst then
rx_data_valid <= '0'; phy_out.rx_data_valid <= '0';
elsif rising_edge(clk) then elsif rising_edge(clk) then
rx_data_valid <= rx_data_valid_i; phy_out.rx_data_valid <= rx_data_valid_i;
rx_data <= phy_rx_data; -- Data should be stable after the time it takes the _valid signal to go through the synchronizer 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 if;
end process rxdvff; end process rxdvff;
@ -136,44 +113,44 @@ begin
port map( port map(
a_clk => phy_clk, a_clk => phy_clk,
a_rst => phy_rst, a_rst => phy_rst,
a_in => phy_rx_error, a_in => phy_phy_out.rx_error,
b_clk => clk, b_clk => clk,
b_rst => rst, b_rst => rst,
b_out => rx_error b_out => phy_out.rx_error
); );
synchronizer_rxa_inst : entity work.synchronizer synchronizer_rxa_inst : entity work.synchronizer
port map( port map(
clk => clk, clk => clk,
rst => rst, rst => rst,
data_in => phy_rx_active, data_in => phy_phy_out.rx_active,
data_out => rx_active data_out => phy_out.rx_active
); );
cdc_strobe_txack_inst : entity work.cdc_strobe cdc_strobe_txack_inst : entity work.cdc_strobe
port map( port map(
a_clk => phy_clk, a_clk => phy_clk,
a_rst => phy_rst, a_rst => phy_rst,
a_in => phy_tx_data_ack, a_in => phy_phy_out.tx_data_ack,
b_clk => clk, b_clk => clk,
b_rst => rst, b_rst => rst,
b_out => tx_data_ack b_out => phy_out.tx_data_ack
); );
synchronizer_crs_inst : entity work.synchronizer synchronizer_crs_inst : entity work.synchronizer
port map( port map(
clk => clk, clk => clk,
rst => rst, rst => rst,
data_in => phy_carrier_detect, data_in => phy_phy_out.carrier_detect,
data_out => carrier_detect data_out => phy_out.carrier_detect
); );
synchronizer_txa_inst : entity work.synchronizer synchronizer_txa_inst : entity work.synchronizer
port map( port map(
clk => clk, clk => clk,
rst => rst, rst => rst,
data_in => phy_tx_active, data_in => phy_phy_out.tx_active,
data_out => tx_active data_out => phy_out.tx_active
); );
end architecture RTL; end architecture rtl;

View File

@ -19,10 +19,27 @@ package trashernet_pkg is
subtype ethertype_t is byte_vector(0 to 1); subtype ethertype_t is byte_vector(0 to 1);
type mac_header_fields is record type mac_header_fields is record
mac_destination : mac_addr_t; -- Destination MAC address mac_destination : mac_addr_t; -- Destination MAC address
mac_source : mac_addr_t; -- Source MAC address mac_source : mac_addr_t; -- Source MAC address
mac_ethertype : ethertype_t; -- Ethertype or length mac_ethertype : ethertype_t; -- Ethertype or length
end record mac_header_fields; end record mac_header_fields;
-- PHY interface
type phy_in_t is record
tx_data : byte; -- TX Data
tx_data_en : std_logic; -- Transmitter enable
end record phy_in_t;
type phy_out_t is record
rx_data : byte; -- RX Data
rx_data_valid : std_logic; -- RX Data valid
rx_active : std_logic; -- RX of packet in progress
tx_data_ack : std_logic; -- Latched data_tx
tx_active : std_logic; -- Transmission in progress
carrier_detect : std_logic; -- Carrier detected
rx_error : std_logic; -- Receive error
end record phy_out_t;
end package trashernet_pkg; end package trashernet_pkg;
package body trashernet_pkg is package body trashernet_pkg is