URL
https://opencores.org/ocsvn/xenie/xenie/trunk
Subversion Repositories xenie
[/] [xenie/] [trunk/] [examples/] [Eth_example/] [ip_repo/] [axi_mdio/] [src/] [mdio_c.vhd] - Rev 4
Compare with Previous | Blame | View Log
--------------------------------------------------------------------------------------------------- -- -- Title : mido -- Design : mdio -- Author : 0 -- Company : 0 -- --------------------------------------------------------------------------------------------------- -- -- File : mido.vhd -- Generated : Mon Apr 5 16:43:44 2004 -- From : interface description file -- By : Itf2Vhdl ver. 1.20 -- --------------------------------------------------------------------------------------------------- -- -- Description : -- --------------------------------------------------------------------------------------------------- --{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {mido} architecture {mido}} library IEEE; use IEEE.STD_LOGIC_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity mdio_c is port( CLK : in std_logic; -- Input clock DIV_CLK : in std_logic_vector(7 downto 0); -- Clock divider, should be X"1C" for 125 MHz CLK PREAMB_SUP : in std_logic; START_OP : in std_logic_vector(1 downto 0); -- Start sequence, should be "01" OPERATION : in std_logic_vector(1 downto 0); -- "01" = write, "10" = read, "00" = adress (Clause 45), "10" = Read & address++ (IEEE 802.3 Clause 45) PHY_ADDR : in std_logic_vector(4 downto 0); -- Phyter address REG_ADDR : in std_logic_vector(4 downto 0); -- Register address or device type (Clause 45) DATA_IN : in std_logic_vector(15 downto 0); -- Data or address (Clause 45) DATA_OUT : out std_logic_vector(15 downto 0); DATA_RDY : out std_logic; RUN_OP : in std_logic; BUSY : out std_logic; MDC : out std_logic; -- MDIO Clock output MDIO_I : in std_logic; -- MDIO Input data MDIO_O : out std_logic; -- MDIO Output data MDIO_OE : out std_logic -- MDIO Output Enable, active low!!! ); end mdio_c; --}} End of automatically maintained section architecture mdio_c of mdio_c is constant DIR_IN : std_logic := '1'; constant DIR_OUT : std_logic := '0'; constant TURN_AROUND_O : std_logic_vector(0 to 1) := "10"; constant OP_READ : std_logic_vector(1 downto 0) := "10"; constant OP_WRITE : std_logic_vector(1 downto 0) := "01"; constant OP_ADDR : std_logic_vector(1 downto 0) := "00"; constant OP_READ_INC : std_logic_vector(1 downto 0) := "11"; type STATE_MDIO_T is (GEN_PREAMBLE, GEN_START, OPCODE, PHY_ADDRESS, REG_ADDRESS, TURN_AROUND, DATA, MDIO_DONE); signal STATE_MDIO : STATE_MDIO_T := GEN_PREAMBLE; signal DIV_CNT : integer range 0 to 255 := 0; signal ENABLE_OP : std_logic := '0'; signal MDC_I : std_logic := '0'; signal sig_MDIO_I : std_logic := '1'; signal MDIO_DIR : std_logic := '0'; signal MDC_FE : std_logic; signal MDIO_GO : std_logic := '1'; signal MDIO_CNT : integer range 0 to 31 := 0; signal START_OP_I : std_logic_vector(0 to 1); signal OPERATION_I : std_logic_vector(0 to 1); signal PHY_ADDR_I, REG_ADDR_I : std_logic_vector(0 to 4); signal DATA_IN_I, DATA_OUT_I : std_logic_vector(0 to 15); signal OP_DONE : std_logic := '0'; begin GEN_CLK: PROCESS(CLK) BEGIN If CLK'event And CLK = '1' Then If ENABLE_OP = '1' Then If DIV_CNT = (CONV_INTEGER(DIV_CLK)) Then DIV_CNT <= 0; MDC_I <= Not MDC_I; Else DIV_CNT <= DIV_CNT + 1; End If; Else MDC_I <= '0'; DIV_CNT <= 0; End If; End If; END PROCESS; MDC_FE <= '1' When DIV_CNT = (CONV_INTEGER(DIV_CLK)) And MDC_I = '1' Else '0'; PROCESS(CLK) BEGIN If CLK'event And CLK = '1' Then If RUN_OP = '1' Then START_OP_I <= START_OP; PHY_ADDR_I <= PHY_ADDR; REG_ADDR_I <= REG_ADDR; OPERATION_I <= OPERATION; DATA_IN_I <= DATA_IN; ENABLE_OP <= '1'; Else If OP_DONE = '1' And MDC_I = '0' Then ENABLE_OP <= '0'; End If; End If; End If; END PROCESS; PROCESS(CLK, MDC_FE, STATE_MDIO) BEGIN If CLK'event And CLK = '1' Then If ENABLE_OP = '1' Then If MDC_FE = '1' Then Case STATE_MDIO is --When WAIT_FOR_START => --MDIO_DIR <= DIR_OUT; --sig_MDIO_I <= '1'; --If MDIO_GO = '1' -- Then -- MDIO_CNT <= 0; -- STATE_MDIO <= GEN_PREAMBLE; -- Else -- STATE_MDIO <= WAIT_FOR_START; -- End If; When GEN_PREAMBLE => sig_MDIO_I <= '1'; MDIO_DIR <= DIR_OUT; If MDIO_CNT < 31 Then MDIO_CNT <= MDIO_CNT + 1; STATE_MDIO <= GEN_PREAMBLE; Else MDIO_CNT <= 0; STATE_MDIO <= GEN_START; End If; When GEN_START => sig_MDIO_I <= START_OP_I(MDIO_CNT); MDIO_DIR <= DIR_OUT; If MDIO_CNT < 1 Then MDIO_CNT <= MDIO_CNT + 1; STATE_MDIO <= GEN_START; Else MDIO_CNT <= 0; STATE_MDIO <= OPCODE; End If; When OPCODE => sig_MDIO_I <= OPERATION_I(MDIO_CNT); If MDIO_CNT < 1 Then MDIO_CNT <= MDIO_CNT + 1; STATE_MDIO <= OPCODE; Else MDIO_CNT <= 0; STATE_MDIO <= PHY_ADDRESS; End If; When PHY_ADDRESS => sig_MDIO_I <= PHY_ADDR_I(MDIO_CNT); If MDIO_CNT < 4 Then MDIO_CNT <= MDIO_CNT + 1; STATE_MDIO <= PHY_ADDRESS; Else MDIO_CNT <= 0; STATE_MDIO <= REG_ADDRESS; End If; When REG_ADDRESS => sig_MDIO_I <= REG_ADDR_I(MDIO_CNT); If MDIO_CNT < 4 Then MDIO_CNT <= MDIO_CNT + 1; STATE_MDIO <= REG_ADDRESS; Else MDIO_CNT <= 0; STATE_MDIO <= TURN_AROUND; End If; When TURN_AROUND => sig_MDIO_I <= TURN_AROUND_O(MDIO_CNT); If MDIO_CNT < 1 Then MDIO_CNT <= MDIO_CNT + 1; STATE_MDIO <= TURN_AROUND; Else MDIO_CNT <= 0; STATE_MDIO <= DATA; End If; Case OPERATION_I is When OP_READ | OP_READ_INC => MDIO_DIR <= DIR_IN; When Others => MDIO_DIR <= DIR_OUT; End Case; When DATA => If MDIO_DIR = DIR_IN Then DATA_OUT_I(MDIO_CNT) <= MDIO_I; Else sig_MDIO_I <= DATA_IN_I(MDIO_CNT); End If; If MDIO_CNT < 15 Then MDIO_CNT <= MDIO_CNT + 1; STATE_MDIO <= DATA; Else MDIO_CNT <= 0; STATE_MDIO <= MDIO_DONE; End If; When MDIO_DONE => -- generate falling edge OP_DONE <= '1'; --MDIO_DIR <= DIR_IN; STATE_MDIO <= GEN_PREAMBLE; -- else -- STATE_MDIO <= MDIO_DONE; -- end if; When Others => STATE_MDIO <= GEN_PREAMBLE; End Case; End If; Else MDIO_CNT <= 0; OP_DONE <= '0'; MDIO_DIR <= DIR_IN; if PREAMB_SUP = '1' then STATE_MDIO <= GEN_START; else STATE_MDIO <= GEN_PREAMBLE; end if; End If; End If; END PROCESS; BUSY <= ENABLE_OP; MDC <= MDC_I; MDIO_O <= sig_MDIO_I; MDIO_OE <= MDIO_DIR; DATA_OUT <= DATA_OUT_I; end mdio_c;