OpenCores
URL https://opencores.org/ocsvn/gigabit_udp_mac/gigabit_udp_mac/trunk

Subversion Repositories gigabit_udp_mac

[/] [gigabit_udp_mac/] [trunk/] [MAC/] [PHY_CONFIG_V6.vhd] - Rev 2

Compare with Previous | Blame | View Log

-------------------------------------------------------------
--	Filename:  PHY_CONFIG_V5.VHD
--	Version: 2
--	Date last modified: 2-4-11
-- Inheritance: 	PHY_CONFIG.VHD, rev2 2-4-11
--
-- description:  Configures a PHY through a MDIO interface.
----------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
 
entity PHY_CONFIG is
	generic (
		PHY_ADDR: std_logic_vector(4 downto 0)	-- PHY Address
	);
    Port ( 
		--// CLK, RESET
		SYNC_RESET: in std_logic;
		CLK: in std_logic;
 
		--// CONTROLS
		CONFIG_CHANGE: in std_logic;
			-- 1 CLK-wide pulse to activate any configuration change below.
			-- Not needed if the default values are acceptable.
		PHY_RESET: in std_logic; 
			-- 1 = PHY software reset, 0 = no reset
		SPEED: in std_logic_vector(1 downto 0);
			-- 00 = force 10 Mbps
			-- 01 = force 100 Mbps
			-- 10 = force 1000 Mbps
			-- 11 = auto-negotiation (default)
		DUPLEX: in std_logic;
			-- 1 = full-duplex (default), 0 = half-duplex
		TEST_MODE: in std_logic_vector(1 downto 0);
			-- 00 = normal mode (default)
			-- 01 = loopback mode
			-- 10 = remote loopback
			-- 11 = led test mode
		POWER_DOWN: in std_logic;
			-- software power down mode. 1 = enabled, 0 = disabled (default).
		CLK_SKEW: in std_logic_vector(15 downto 0);
			-- Register 260 RGMII clock and control pad skew
 
		--// MONITORING
		SREG_READ_START: in std_logic;
			-- 1 CLK wide pulse to start read transaction
			-- will be ignored if the previous transaction is yet to be completed.
		SREG_REGAD: in std_logic_vector(8 downto 0);	
			-- 32 register address space for the PHY 
			--  0 - 15 are standard PHY registers as per IEEE specification.
			-- 16 - 31 are vendor-specific registers
			-- 256+ are extended registers
		SREG_DATA : OUT std_logic_vector(15 downto 0);
			-- 16-bit status register. Read when SREG_SAMPLE_CLK = '1'
		SREG_SAMPLE_CLK: out std_logic;
 
		--// BASIC STATUS REPORT (status register 1)
		LINK_STATUS: out std_logic;  
			-- 0 = link down, 1 = link up
		--// serial interface. connect to PHY 
		MCLK: out std_logic;
		MDI: in std_logic;  -- MDIO input
		MDO: out std_logic;  -- MDIO output
		MDT: out std_logic  -- MDIO tri-state
 
);
end entity;
 
architecture Behavioral of PHY_CONFIG is
--------------------------------------------------------
--      COMPONENTS
--------------------------------------------------------
	COMPONENT MII_MI_V6
	GENERIC (
		PHY_ADDR: std_logic_vector(4 downto 0)
	);	
	PORT(
		SYNC_RESET : IN std_logic;
		CLK : IN std_logic;
		MI_REGAD : IN std_logic_vector(4 downto 0);
		MI_TX_DATA : IN std_logic_vector(15 downto 0);
		MI_READ_START : IN std_logic;
		MI_WRITE_START : IN std_logic;    
		MDI: in std_logic;  -- MDIO input
		MDO: out std_logic;  -- MDIO output
		MDT: out std_logic;  -- MDIO tri-state
		MI_RX_DATA : OUT std_logic_vector(15 downto 0);
		MI_TRANSACTION_COMPLETE : OUT std_logic;
		MCLK : OUT std_logic
		);
	END COMPONENT;
--------------------------------------------------------
--     SIGNALS
--------------------------------------------------------
signal STATE: std_logic_vector(3 downto 0) := "0000";
signal MI_WRITE_START: std_logic := '0';
signal MI_REGAD: std_logic_vector(4 downto 0) := "00000";
signal MI_TX_DATA: std_logic_vector(15 downto 0);
signal MI_READ_START: std_logic := '0';
signal MI_RX_DATA: std_logic_vector(15 downto 0);
signal MI_TRANSACTION_COMPLETE: std_logic;
signal PHY_RESET_D: std_logic;
signal SPEED_D: std_logic_vector(1 downto 0);
signal LOOPBACK_MODE: std_logic;
signal AUTONEG: std_logic;
signal POWER_DOWN_D: std_logic;
signal DUPLEX_D: std_logic;
signal REMOTE_LOOPBACK: std_logic;
signal LED_TEST_MODE: std_logic;
 
constant RGMII_INBAND_STATUS_EN: std_logic := '1'; -- enable in-band status reporting in RGMII
signal SREG_SAMPLE_CLK_local: std_logic := '0';
--------------------------------------------------------
--      IMPLEMENTATION
--------------------------------------------------------
begin
 
---- save the configuration so that it does not change while the configuration is in progress
RECLOCK_001: process(CLK)
begin
	if rising_edge(CLK) then
		if(STATE = 0) and (CONFIG_CHANGE = '1') then
			PHY_RESET_D <= PHY_RESET;
			SPEED_D <= SPEED;
			DUPLEX_D <= DUPLEX;
			POWER_DOWN_D <= POWER_DOWN;
 
			if(SPEED = "11") then
				AUTONEG <= '1';
			else
				AUTONEG <= '0';
			end if;
 
			case TEST_MODE is
				when "00" => 
					LOOPBACK_MODE <= '0';
					REMOTE_LOOPBACK <= '0';
					LED_TEST_MODE <= '0';
				when "01" => 
					LOOPBACK_MODE <= '1';
					REMOTE_LOOPBACK <= '0';
					LED_TEST_MODE <= '0';
				when "10" => 
					LOOPBACK_MODE <= '0';
					REMOTE_LOOPBACK <= '1';
					LED_TEST_MODE <= '0';
				when others => 
					LOOPBACK_MODE <= '0';
					REMOTE_LOOPBACK <= '0';
					LED_TEST_MODE <= '1';
			end case;
 
		end if;
	end if;
end process;
-- state machine
STATE_GEN: process(CLK)
begin
	if rising_edge(CLK) then
		if(SYNC_RESET = '1') then
			STATE <= (others => '0');
			MI_WRITE_START <= '0';
			MI_READ_START <= '0';
 
		-- WRITE ALL CONFIGURATION REGISTERS
		elsif(STATE = 0) and (CONFIG_CHANGE = '1') then
			-- triggers a PHY reconfiguration. await PHY MDIO availability
			STATE <= STATE + 1;
 
		elsif(STATE = 1) and (MI_TRANSACTION_COMPLETE = '1') then
			-- PHY is ready for next transaction.
			-- Register 0: basic control (applicable to all: GMII, MII, RGMII)
			STATE <= STATE + 1;
			MI_REGAD <= "00000";
			MI_TX_DATA(15 downto 8) <= PHY_RESET_D & LOOPBACK_MODE & SPEED_D(0) & AUTONEG & POWER_DOWN_D & "00" & DUPLEX_D;
			MI_TX_DATA(7 downto 0) <= "0" & SPEED_D(1) & "000000";
			MI_WRITE_START <= '1';
 
-- tested for Micrel KSZ90212RN -------
-- adjust as needed depending on the PHY 	(the extended registers vary depending on the manufacturer/model).		
		elsif(STATE = 2) and (MI_TRANSACTION_COMPLETE = '1') then 
			STATE <= (others => '0');
		-- READ ONE STATUS REGISTER	
		elsif(STATE = 0) and (SREG_READ_START = '1') and (SREG_REGAD(8) = '0') then
			-- triggers a PHY status read. await PHY MDIO availability
			STATE <= "1000";
		elsif(STATE = 8) and (MI_TRANSACTION_COMPLETE = '1') and (SREG_REGAD(8) = '0') then
			-- PHY is ready for next transaction.
			STATE <= STATE + 1;
			MI_REGAD <= SREG_REGAD(4 downto 0);  
			MI_READ_START <= '1';
		elsif(STATE = 9) and (MI_TRANSACTION_COMPLETE = '1') then
			-- we are done reading a status register! Going back to idle.
			STATE <= (others => '0');
			SREG_SAMPLE_CLK_local <= '1';
 
 
		-- READ ONE EXTENDED REGISTER	
		elsif(STATE = 0) and (SREG_READ_START = '1') and (SREG_REGAD(8) = '1') then
			-- Extended register (1/2)
			STATE <= "1000";
			MI_REGAD <= "01011";  
			MI_TX_DATA <= "0000000" & SREG_REGAD;  -- read extended register
			MI_WRITE_START <= '1';
		elsif(STATE = 8) and (MI_TRANSACTION_COMPLETE = '1') and (SREG_REGAD(8) = '1') then
			-- triggers a PHY status read. await PHY MDIO availability
			STATE <= STATE + 1;
			MI_REGAD <= "01101";  
			MI_READ_START <= '1';
		elsif(STATE = 9) and (MI_TRANSACTION_COMPLETE = '1') then
			-- we are done reading a status register! Going back to idle.
			STATE <= (others => '0');
			SREG_SAMPLE_CLK_local <= '1';
 
		-- PERIODIC READ BASIC STATUS: LINK
		elsif(STATE = 0) and (MI_TRANSACTION_COMPLETE = '1') then
			-- Register 1: basic status (applicable to all: GMII, MII, RGMII)
			STATE <= "1010";
			MI_REGAD <= "10001";  
			MI_READ_START <= '1';
		elsif(STATE = 10) and (MI_TRANSACTION_COMPLETE = '1') then
			-- we are done reading a status register! Going back to idle.
			STATE <= (others => '0');
--			LINK_STATUS <= MI_RX_DATA(2); commented by KED
 
		else
			MI_WRITE_START <= '0';
			MI_READ_START <= '0';
			SREG_SAMPLE_CLK_local <= '0';
 
		end if;
	end if;
end process;
 
LINK_STATUS <= '1';--; Added by KED
 
-- latch status register
SREGOUT_001:  process(CLK)
begin
	if rising_edge(CLK) then
		SREG_SAMPLE_CLK <= SREG_SAMPLE_CLK_local;
 
		if(SREG_SAMPLE_CLK_local = '1') then
			SREG_DATA <= MI_RX_DATA;
		end if;
	end if;
end process;
 
Inst_MII_MI: MII_MI_V6
GENERIC MAP(
	PHY_ADDR => PHY_ADDR
)
PORT MAP(
	SYNC_RESET => SYNC_RESET,
	CLK => CLK,
	MI_REGAD => MI_REGAD,
	MI_TX_DATA => MI_TX_DATA,
	MI_RX_DATA => MI_RX_DATA,
	MI_READ_START => MI_READ_START,
	MI_WRITE_START => MI_WRITE_START,
	MI_TRANSACTION_COMPLETE => MI_TRANSACTION_COMPLETE,
	MCLK => MCLK,
	MDI => MDI,
	MDO => MDO,
	MDT => MDT
);
 
end Behavioral;
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.