summaryrefslogtreecommitdiff
path: root/lib/ethernet/components/mii_management_transmit.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ethernet/components/mii_management_transmit.vhd')
-rw-r--r--lib/ethernet/components/mii_management_transmit.vhd178
1 files changed, 178 insertions, 0 deletions
diff --git a/lib/ethernet/components/mii_management_transmit.vhd b/lib/ethernet/components/mii_management_transmit.vhd
new file mode 100644
index 0000000..4a81d8f
--- /dev/null
+++ b/lib/ethernet/components/mii_management_transmit.vhd
@@ -0,0 +1,178 @@
+------------------------------------------------------------------
+-- _____ ______ _____ -
+-- |_ _| | ____|/ ____| 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; \ No newline at end of file