From 643d40c1c4d154e0ac922402663349521c372e3a Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 2 Aug 2010 11:00:08 +0200 Subject: Add packages needed for TSE MAC --- lib/ethernet/components/rmii_phy_to_mii_mac.vhd | 217 ++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 lib/ethernet/components/rmii_phy_to_mii_mac.vhd (limited to 'lib/ethernet/components/rmii_phy_to_mii_mac.vhd') diff --git a/lib/ethernet/components/rmii_phy_to_mii_mac.vhd b/lib/ethernet/components/rmii_phy_to_mii_mac.vhd new file mode 100644 index 0000000..09227c6 --- /dev/null +++ b/lib/ethernet/components/rmii_phy_to_mii_mac.vhd @@ -0,0 +1,217 @@ +------------------------------------------------------------------ +-- _____ ______ _____ - +-- |_ _| | ____|/ ____| - +-- | | _ __ | |__ | (___ Institute of Embedded Systems - +-- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - +-- _| |_| | | | |____ ____) | (University of Applied Sciences) - +-- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - +------------------------------------------------------------------ +-- +-- Project : SInet +-- Description : Connects the data interface of a PHY in RMMI Mode and a MAC +-- in MII Mode +-- $LastChangedDate: 2006-11-14 12:14:54 +0100 (Tue, 14 Nov 2006) $ +-- $Rev: 1358 $ +-- $Author: beut $ +----------------------------------------------------------------- +-- +-- Change History +-- Date |Name |Modification +------------|----------|----------------------------------------- +-- 20.02.09 | beut | file ceated +----------------------------------------------------------------- +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +package rmii_phy_to_mii_mac_pkg is + component rmii_phy_to_mii_mac + port ( + reset_n_i : in std_logic; + clk_25_i : in std_logic; + clk_50_i : in std_logic; + rmii_crs_i : in std_logic; + + -- Transmit Path + mii_tx_en_i : in std_logic; + mii_txd_i : in std_logic_vector(3 downto 0); + rmii_tx_en_o : out std_logic; + rmii_txd_o : out std_logic_vector(1 downto 0); + + -- Receive Path + rmii_rx_dv_i : in std_logic; + rmii_rxd_i : in std_logic_vector(1 downto 0); + mii_rx_dv_o : out std_logic; + mii_rxd_o : out std_logic_vector(3 downto 0) + ); + end component rmii_phy_to_mii_mac; +end package rmii_phy_to_mii_mac_pkg; + +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +entity rmii_phy_to_mii_mac is + port ( + reset_n_i : in std_logic; + clk_25_i : in std_logic; + clk_50_i : in std_logic; + rmii_crs_i : in std_logic; + + -- Transmit Path + mii_tx_en_i : in std_logic; + mii_txd_i : in std_logic_vector(3 downto 0); + rmii_tx_en_o : out std_logic; + rmii_txd_o : out std_logic_vector(1 downto 0); + + -- Receive Path + rmii_rx_dv_i : in std_logic; + rmii_rxd_i : in std_logic_vector(1 downto 0); + mii_rx_dv_o : out std_logic; + mii_rxd_o : out std_logic_vector(3 downto 0) + ); +end rmii_phy_to_mii_mac; + + +architecture behavior of rmii_phy_to_mii_mac is + + signal rmii_txd_next, rmii_txd_curr : std_logic; + signal clk_25_sync_to_data : std_logic; + signal clk_25_toggle, clk_50_toggle : std_logic; + signal rmii_rxd_buffer : std_logic_vector(5 downto 0); + signal mii_txd_buffer : std_logic_vector(3 downto 0); + signal buffer_cnt : integer range 0 to 1; + signal clk_50_en : std_logic; + signal rmii_rx_dv_f : std_logic; + signal mii_rx_dv_f : std_logic; + signal mii_rx_dv_ff : std_logic; + signal rmii_valid_sof : std_logic; + +begin + + ----------------------------------------------------------------- + -- Clock 50 Enable Gnerating (is high if clock 25Mhz and Clock 50 MHz are rising + ----------------------------------------------------------------- + + clock_25_proc: process (clk_25_i) + begin + if rising_edge(clk_25_i) then + clk_25_toggle <= not clk_25_toggle; + end if; + end process; + + -- The clock enable muxes data in 25MHz freqency and has the same timing like data and not the clock! + clock_50_proc: process (reset_n_i, clk_50_i) + begin + if reset_n_i = '0' then + clk_50_toggle <= '0'; + clk_50_en <= '0'; + elsif rising_edge(clk_50_i) then + clk_50_toggle <= clk_25_toggle; + -- edge detection + clk_50_en <= clk_25_toggle xor clk_50_toggle; --25 MHz clk sync to data of 50MHz + end if; + end process; + ----------------------------------------------------------------- + + + ----------------------------------------------------------------- + -- Data Muxing from MAC to PHY + ----------------------------------------------------------------- + mii_to_rmii_proc : process (clk_50_en, mii_txd_i, mii_txd_buffer) + begin + if clk_50_en = '0' then + rmii_txd_o <= mii_txd_buffer(1 downto 0); + else + rmii_txd_o <= mii_txd_buffer(3 downto 2); + end if; + end process; + + rmii_tx_en_proc: process (reset_n_i, clk_50_i) + begin + if reset_n_i = '0' then + rmii_tx_en_o <= '0'; + elsif rising_edge(clk_50_i) then + if clk_50_en = '1' then -- data changes after a beginning of 25MHz cycle + mii_txd_buffer <= mii_txd_i; + rmii_tx_en_o <= mii_tx_en_i; + end if; + end if; + end process; + + ----------------------------------------------------------------- + + + ----------------------------------------------------------------- + -- Data Muxing from PHY to MAC + ----------------------------------------------------------------- + + -- Data buffern + buffer_proc: process (reset_n_i, clk_50_i) + begin + if reset_n_i = '0' then + rmii_rxd_buffer <= (others => '0'); + elsif rising_edge(clk_50_i) then + rmii_rxd_buffer(1 downto 0) <= rmii_rxd_buffer(3 downto 2); + rmii_rxd_buffer(3 downto 2) <= rmii_rxd_buffer(5 downto 4); + rmii_rxd_buffer(5 downto 4) <= rmii_rxd_i; + end if; + end process; + + rmii_rx_dv_proc: process (reset_n_i, clk_50_i) + begin + if reset_n_i = '0' then + mii_rx_dv_f <= '0'; + mii_rx_dv_ff <= '0'; + mii_rxd_o <= (others => '0'); + elsif rising_edge(clk_50_i) then + if clk_50_en = '1' then + + if rmii_valid_sof = '1' then --only valid if the packet from phy is valid + mii_rx_dv_f <= rmii_rx_dv_i; + mii_rx_dv_ff <= mii_rx_dv_f; -- valid is two 25 MHz clockcycles later + end if; + + if buffer_cnt = 1 then -- depends on the rmii dv signal + mii_rxd_o <= rmii_rxd_buffer(3 downto 0); -- Three step buffer + else + mii_rxd_o <= rmii_rxd_buffer(5 downto 2); -- Two step buffer + end if; + end if; + end if; + end process; + mii_rx_dv_o <= mii_rx_dv_ff ; + + -- counts the 50MHz clocks before rmii dv signal goes high before a 25MHZ Clock + buffer_cnt_proc: process (reset_n_i, clk_50_i) + begin + if reset_n_i = '0' then + buffer_cnt <= 0; + elsif rising_edge(clk_50_i) then + if (rmii_rx_dv_i = '1' and rmii_rx_dv_f = '0') and clk_50_en = '0' then + buffer_cnt <= 1; + elsif (rmii_rx_dv_i = '1' and rmii_rx_dv_f = '0') and clk_50_en = '1' then + buffer_cnt <= 0; + end if; + end if; + end process; + + rmii_valid_sof_proc: process (reset_n_i, clk_50_i) + begin + if reset_n_i = '0' then + rmii_valid_sof <= '0'; + rmii_rx_dv_f <= '0'; + elsif rising_edge(clk_50_i) then + rmii_rx_dv_f <= rmii_rx_dv_i; + if rmii_crs_i = '1' and rmii_rx_dv_f = '0' and rmii_rx_dv_i = '1' then -- start of a valid frame + rmii_valid_sof <= '1'; + end if; + end if; + end process; + + + + + + +end behavior; -- cgit v1.2.3-54-g00ecf