-- -------------------------------------------------------------------------- -- -- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs -- -- -------------------------------------------------------------------------- -- -- TODO -- -------------------------------------------------------------------------- -- -- Author : Markus Koch -- Contributors : None -- License : Mozilla Public License (MPL) Version 2 -- -------------------------------------------------------------------------- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library trashernet; use trashernet.trashernet_pkg.all; library generics; use generics.all; use generics.wishbone_pkg.all; entity trashernet_phy_wb is generic( F_CLK : in integer; -- Clock frequency in Hz F_CLK_PHY : in integer ); port( -- Global clk : in std_logic; -- Global clock phy_clk : in std_logic; -- PHY clock rst : in std_logic; -- Asynchronous reset -- Wishbone IF wb_o : out wishbone_slave_out; -- Wishbone bus (out) wb_i : in wishbone_slave_in; -- Wishbone bus (in) -- Ethernet physical signals rx_p : in std_logic; tx_p : out std_logic; tx_n : out std_logic ); end entity trashernet_phy_wb; architecture RTL of trashernet_phy_wb is -- PHY application interface signal phy_out : phy_out_t; -- PHY application IF (out) signal phy_in : phy_in_t; -- PHY application IF (in) signal wb_adr : unsigned(2 downto 2); signal status_register : std_logic_vector(31 downto 0); signal rx_fifo_read : std_logic; signal rx_fifo_data : std_logic_vector(7 downto 0); signal tx_fifo_write : std_logic; signal tx_fifo_commit : std_logic; signal tx_fifo_empty : std_logic; signal tx_fifo_data : std_logic_vector(7 downto 0); begin trashernet_phy_inst : entity trashernet.trashernet_phy_cdc generic map( F_CLK => F_CLK, F_CLK_PHY => F_CLK_PHY ) port map( clk => clk, phy_clk => phy_clk, rst => rst, phy_out => phy_out, phy_in => phy_in, rx_p => rx_p, tx_p => tx_p, tx_n => tx_n ); rx_fifo_inst : entity generics.fifo_block generic map( SIZE => 2047 ) port map( clk => clk, rst_a => '0', clr => rst, data_in => phy_out.rx_data, write => phy_out.rx_data_valid, commit => not phy_out.rx_active, abort => '0', full => open, data_out => rx_fifo_data, data_first => open, empty => open, read => rx_fifo_read, usage => open ); tx_fifo_inst : entity generics.fifo_block generic map( SIZE => 2047 ) port map( clk => clk, rst_a => '0', clr => rst, data_in => wb_i.dat(7 downto 0), write => tx_fifo_write, commit => tx_fifo_commit, abort => '0', full => open, data_out => tx_fifo_data, data_first => open, empty => tx_fifo_empty, read => phy_out.tx_data_ack, usage => open ); wb_adr <= unsigned(wb_i.adr(wb_adr'range)); wbif : process(clk, rst) is begin if rst then wb_o.ack <= '0'; rx_fifo_read <= '0'; tx_fifo_write <= '0'; tx_fifo_commit <= '0'; elsif rising_edge(clk) then wb_o.ack <= '0'; rx_fifo_read <= '0'; tx_fifo_write <= '0'; tx_fifo_commit <= '0'; if (wb_i.cyc and wb_i.stb) then wb_o.ack <= '1'; if wb_adr = 0 then wb_o.dat <= status_register; if wb_o.ack = '0' then if wb_i.we = '1' then tx_fifo_commit <= '1'; end if; end if; else wb_o.dat <= (others => '0'); if wb_o.ack = '0' then if wb_i.we = '1' then tx_fifo_write <= '1'; else rx_fifo_read <= '1'; end if; end if; wb_o.dat(7 downto 0) <= rx_fifo_data; end if; end if; end if; end process wbif; wb_o.err <= '0'; wb_o.rty <= '1'; wb_o.stall <= '0'; phy_in.tx_data_en <= not tx_fifo_empty; -- FIXME: this does not care about inter-packet gaps indicated by `data_first` phy_in.tx_data <= tx_fifo_data; status_register <= (x"0000" & x"000" & "000" & phy_out.carrier_detect); end architecture RTL;