------------------------------------------------------------------ -- _____ ______ _____ - -- |_ _| | ____|/ ____| Institute of Embedded Systems - -- | | _ __ | |__ | (___ Zuercher Hochschule fuer - -- | | | '_ \| __| \___ \ angewandte Wissenschaften - -- _| |_| | | | |____ ____) | (University of Applied Sciences) - -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - ------------------------------------------------------------------ -- -- Project : SInet -- Module : -- Description : MDIO low level protocol -- -- $LastChangedDate: 2008-10-31 12:06:00 +0100 (Fri, 31 Oct 2008) $ -- $Rev: 1905 $ -- $Author: ffar $ ----------------------------------------------------------------- -- -- Change History -- Date |Name |Modification ----------------------------------------------------------------- -- 02.11.07 | ffar | file created based on library component -- | | from glc (27.09.05) ----------------------------------------------------------------- library ieee; use ieee.numeric_std.all; use ieee.std_logic_1164.all; package mii_management_transmit_pkg is component mii_management_transmit generic( G_CLK_DIVIDER : in integer ); port( clk : in std_logic; reset_n : in std_logic; phy_addr_i : in std_logic_vector(4 downto 0); phy_reg_i : in std_logic_vector(4 downto 0); phy_data_i : in std_logic_vector(15 downto 0); phy_data_o : out std_logic_vector(15 downto 0); send_i : in std_logic; read_i : in std_logic; done_o : out std_logic; mdc_pad_o : out std_logic; md_pad_i : in std_logic; md_pad_o : out std_logic; md_padoe_o : out std_logic ); end component mii_management_transmit; end package mii_management_transmit_pkg; library ieee; use ieee.numeric_std.all; use ieee.std_logic_1164.all; entity mii_management_transmit is generic( G_CLK_DIVIDER : in integer ); port( clk : in std_logic; reset_n : in std_logic; phy_addr_i : in std_logic_vector(4 downto 0); phy_reg_i : in std_logic_vector(4 downto 0); phy_data_i : in std_logic_vector(15 downto 0); phy_data_o : out std_logic_vector(15 downto 0); send_i : in std_logic; read_i : in std_logic; done_o : out std_logic; mdc_pad_o : out std_logic; md_pad_i : in std_logic; md_pad_o : out std_logic; md_padoe_o : out std_logic ); end mii_management_transmit; architecture rtl of mii_management_transmit is signal confdata : std_logic_vector(32 downto 0) := (others => '0'); signal rec_data : std_logic_vector(15 downto 0); signal conf_v : integer range 0 to 64; signal cnt_v : integer range 0 to G_CLK_DIVIDER; signal mdc : std_logic; signal send : std_logic; begin phy_data_o <= rec_data; phy_config : process(clk, reset_n, mdc, send_i, read_i, phy_addr_i, phy_reg_i, phy_data_i, md_pad_i, conf_v) begin if reset_n = '0' then conf_v <= 0; md_pad_o <= '0'; md_padoe_o <= '0'; done_o <= '1'; confdata <= (others => '0'); rec_data <= (others => '0'); send <= '0'; elsif clk'event and clk = '1' then if conf_v > 32 then -- send preamble done_o <= '0'; md_pad_o <= '1'; if mdc = '1' then conf_v <= conf_v - 1; end if; elsif conf_v > 0 and send = '1' then -- send data if mdc = '1' then md_pad_o <= confdata(conf_v); conf_v <= conf_v - 1; end if; elsif conf_v > 16 and send = '0' then -- receive data if mdc = '1' then md_pad_o <= confdata(conf_v); conf_v <= conf_v - 1; end if; elsif conf_v > 0 and send = '0' then -- store data if mdc = '1' then rec_data(15 downto 1) <= rec_data(14 downto 0); rec_data(0) <= md_pad_i; conf_v <= conf_v - 1; end if; elsif send_i = '1' then confdata <= "0101" & phy_addr_i & phy_reg_i & "10" & phy_data_i & "0"; conf_v <= 64; send <= '1'; done_o <= '0'; elsif read_i = '1' then confdata <= "0110" & phy_addr_i & phy_reg_i & X"0000" & "000"; conf_v <= 64; send <= '0'; done_o <= '0'; else send <= '0'; md_pad_o <= '0'; done_o <= '1'; end if; if send = '1' OR conf_v >= 18 then md_padoe_o <= '1'; else md_padoe_o <= '0'; end if; end if; end process; clk_div : process(clk, reset_n, cnt_v) begin if reset_n = '0' then cnt_v <= 0; mdc_pad_o <= '0'; mdc <= '0'; elsif clk'event and clk = '1' then mdc <= '0'; if cnt_v = G_CLK_DIVIDER/2+1 then mdc_pad_o <= '0'; mdc <= '1'; cnt_v <= cnt_v - 1; elsif cnt_v <= 1 then mdc_pad_o <= '1'; cnt_v <= G_CLK_DIVIDER; else cnt_v <= cnt_v - 1; end if; end if; end process; end rtl;