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] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 boa_a_m
-------------------------------------------------------------
2
--      Filename:  PHY_CONFIG_V5.VHD
3
--      Version: 2
4
--      Date last modified: 2-4-11
5
-- Inheritance:         PHY_CONFIG.VHD, rev2 2-4-11
6
--
7
-- description:  Configures a PHY through a MDIO interface.
8
----------------------------------------------------------------
9
library IEEE;
10
use IEEE.STD_LOGIC_1164.ALL;
11
use IEEE.STD_LOGIC_ARITH.ALL;
12
use IEEE.STD_LOGIC_UNSIGNED.ALL;
13
 
14
---- Uncomment the following library declaration if instantiating
15
---- any Xilinx primitives in this code.
16
--library UNISIM;
17
--use UNISIM.VComponents.all;
18
 
19
entity PHY_CONFIG is
20
        generic (
21
                PHY_ADDR: std_logic_vector(4 downto 0)   -- PHY Address
22
        );
23
    Port (
24
                --// CLK, RESET
25
                SYNC_RESET: in std_logic;
26
                CLK: in std_logic;
27
 
28
                --// CONTROLS
29
                CONFIG_CHANGE: in std_logic;
30
                        -- 1 CLK-wide pulse to activate any configuration change below.
31
                        -- Not needed if the default values are acceptable.
32
                PHY_RESET: in std_logic;
33
                        -- 1 = PHY software reset, 0 = no reset
34
                SPEED: in std_logic_vector(1 downto 0);
35
                        -- 00 = force 10 Mbps
36
                        -- 01 = force 100 Mbps
37
                        -- 10 = force 1000 Mbps
38
                        -- 11 = auto-negotiation (default)
39
                DUPLEX: in std_logic;
40
                        -- 1 = full-duplex (default), 0 = half-duplex
41
                TEST_MODE: in std_logic_vector(1 downto 0);
42
                        -- 00 = normal mode (default)
43
                        -- 01 = loopback mode
44
                        -- 10 = remote loopback
45
                        -- 11 = led test mode
46
                POWER_DOWN: in std_logic;
47
                        -- software power down mode. 1 = enabled, 0 = disabled (default).
48
                CLK_SKEW: in std_logic_vector(15 downto 0);
49
                        -- Register 260 RGMII clock and control pad skew
50
 
51
                --// MONITORING
52
                SREG_READ_START: in std_logic;
53
                        -- 1 CLK wide pulse to start read transaction
54
                        -- will be ignored if the previous transaction is yet to be completed.
55
                SREG_REGAD: in std_logic_vector(8 downto 0);
56
                        -- 32 register address space for the PHY 
57
                        --  0 - 15 are standard PHY registers as per IEEE specification.
58
                        -- 16 - 31 are vendor-specific registers
59
                        -- 256+ are extended registers
60
                SREG_DATA : OUT std_logic_vector(15 downto 0);
61
                        -- 16-bit status register. Read when SREG_SAMPLE_CLK = '1'
62
                SREG_SAMPLE_CLK: out std_logic;
63
 
64
                --// BASIC STATUS REPORT (status register 1)
65
                LINK_STATUS: out std_logic;
66
                        -- 0 = link down, 1 = link up
67
                --// serial interface. connect to PHY 
68
                MCLK: out std_logic;
69
                MDI: in std_logic;  -- MDIO input
70
                MDO: out std_logic;  -- MDIO output
71
                MDT: out std_logic  -- MDIO tri-state
72
 
73
);
74
end entity;
75
 
76
architecture Behavioral of PHY_CONFIG is
77
--------------------------------------------------------
78
--      COMPONENTS
79
--------------------------------------------------------
80
        COMPONENT MII_MI_V6
81
        GENERIC (
82
                PHY_ADDR: std_logic_vector(4 downto 0)
83
        );
84
        PORT(
85
                SYNC_RESET : IN std_logic;
86
                CLK : IN std_logic;
87
                MI_REGAD : IN std_logic_vector(4 downto 0);
88
                MI_TX_DATA : IN std_logic_vector(15 downto 0);
89
                MI_READ_START : IN std_logic;
90
                MI_WRITE_START : IN std_logic;
91
                MDI: in std_logic;  -- MDIO input
92
                MDO: out std_logic;  -- MDIO output
93
                MDT: out std_logic;  -- MDIO tri-state
94
                MI_RX_DATA : OUT std_logic_vector(15 downto 0);
95
                MI_TRANSACTION_COMPLETE : OUT std_logic;
96
                MCLK : OUT std_logic
97
                );
98
        END COMPONENT;
99
--------------------------------------------------------
100
--     SIGNALS
101
--------------------------------------------------------
102
signal STATE: std_logic_vector(3 downto 0) := "0000";
103
signal MI_WRITE_START: std_logic := '0';
104
signal MI_REGAD: std_logic_vector(4 downto 0) := "00000";
105
signal MI_TX_DATA: std_logic_vector(15 downto 0);
106
signal MI_READ_START: std_logic := '0';
107
signal MI_RX_DATA: std_logic_vector(15 downto 0);
108
signal MI_TRANSACTION_COMPLETE: std_logic;
109
signal PHY_RESET_D: std_logic;
110
signal SPEED_D: std_logic_vector(1 downto 0);
111
signal LOOPBACK_MODE: std_logic;
112
signal AUTONEG: std_logic;
113
signal POWER_DOWN_D: std_logic;
114
signal DUPLEX_D: std_logic;
115
signal REMOTE_LOOPBACK: std_logic;
116
signal LED_TEST_MODE: std_logic;
117
 
118
constant RGMII_INBAND_STATUS_EN: std_logic := '1'; -- enable in-band status reporting in RGMII
119
signal SREG_SAMPLE_CLK_local: std_logic := '0';
120
--------------------------------------------------------
121
--      IMPLEMENTATION
122
--------------------------------------------------------
123
begin
124
 
125
---- save the configuration so that it does not change while the configuration is in progress
126
RECLOCK_001: process(CLK)
127
begin
128
        if rising_edge(CLK) then
129
                if(STATE = 0) and (CONFIG_CHANGE = '1') then
130
                        PHY_RESET_D <= PHY_RESET;
131
                        SPEED_D <= SPEED;
132
                        DUPLEX_D <= DUPLEX;
133
                        POWER_DOWN_D <= POWER_DOWN;
134
 
135
                        if(SPEED = "11") then
136
                                AUTONEG <= '1';
137
                        else
138
                                AUTONEG <= '0';
139
                        end if;
140
 
141
                        case TEST_MODE is
142
                                when "00" =>
143
                                        LOOPBACK_MODE <= '0';
144
                                        REMOTE_LOOPBACK <= '0';
145
                                        LED_TEST_MODE <= '0';
146
                                when "01" =>
147
                                        LOOPBACK_MODE <= '1';
148
                                        REMOTE_LOOPBACK <= '0';
149
                                        LED_TEST_MODE <= '0';
150
                                when "10" =>
151
                                        LOOPBACK_MODE <= '0';
152
                                        REMOTE_LOOPBACK <= '1';
153
                                        LED_TEST_MODE <= '0';
154
                                when others =>
155
                                        LOOPBACK_MODE <= '0';
156
                                        REMOTE_LOOPBACK <= '0';
157
                                        LED_TEST_MODE <= '1';
158
                        end case;
159
 
160
                end if;
161
        end if;
162
end process;
163
-- state machine
164
STATE_GEN: process(CLK)
165
begin
166
        if rising_edge(CLK) then
167
                if(SYNC_RESET = '1') then
168
                        STATE <= (others => '0');
169
                        MI_WRITE_START <= '0';
170
                        MI_READ_START <= '0';
171
 
172
                -- WRITE ALL CONFIGURATION REGISTERS
173
                elsif(STATE = 0) and (CONFIG_CHANGE = '1') then
174
                        -- triggers a PHY reconfiguration. await PHY MDIO availability
175
                        STATE <= STATE + 1;
176
 
177
                elsif(STATE = 1) and (MI_TRANSACTION_COMPLETE = '1') then
178
                        -- PHY is ready for next transaction.
179
                        -- Register 0: basic control (applicable to all: GMII, MII, RGMII)
180
                        STATE <= STATE + 1;
181
                        MI_REGAD <= "00000";
182
                        MI_TX_DATA(15 downto 8) <= PHY_RESET_D & LOOPBACK_MODE & SPEED_D(0) & AUTONEG & POWER_DOWN_D & "00" & DUPLEX_D;
183
                        MI_TX_DATA(7 downto 0) <= "0" & SPEED_D(1) & "000000";
184
                        MI_WRITE_START <= '1';
185
 
186
-- tested for Micrel KSZ90212RN -------
187
-- adjust as needed depending on the PHY        (the extended registers vary depending on the manufacturer/model).              
188
                elsif(STATE = 2) and (MI_TRANSACTION_COMPLETE = '1') then
189
                        STATE <= (others => '0');
190
                -- READ ONE STATUS REGISTER     
191
                elsif(STATE = 0) and (SREG_READ_START = '1') and (SREG_REGAD(8) = '0') then
192
                        -- triggers a PHY status read. await PHY MDIO availability
193
                        STATE <= "1000";
194
                elsif(STATE = 8) and (MI_TRANSACTION_COMPLETE = '1') and (SREG_REGAD(8) = '0') then
195
                        -- PHY is ready for next transaction.
196
                        STATE <= STATE + 1;
197
                        MI_REGAD <= SREG_REGAD(4 downto 0);
198
                        MI_READ_START <= '1';
199
                elsif(STATE = 9) and (MI_TRANSACTION_COMPLETE = '1') then
200
                        -- we are done reading a status register! Going back to idle.
201
                        STATE <= (others => '0');
202
                        SREG_SAMPLE_CLK_local <= '1';
203
 
204
 
205
                -- READ ONE EXTENDED REGISTER   
206
                elsif(STATE = 0) and (SREG_READ_START = '1') and (SREG_REGAD(8) = '1') then
207
                        -- Extended register (1/2)
208
                        STATE <= "1000";
209
                        MI_REGAD <= "01011";
210
                        MI_TX_DATA <= "0000000" & SREG_REGAD;  -- read extended register
211
                        MI_WRITE_START <= '1';
212
                elsif(STATE = 8) and (MI_TRANSACTION_COMPLETE = '1') and (SREG_REGAD(8) = '1') then
213
                        -- triggers a PHY status read. await PHY MDIO availability
214
                        STATE <= STATE + 1;
215
                        MI_REGAD <= "01101";
216
                        MI_READ_START <= '1';
217
                elsif(STATE = 9) and (MI_TRANSACTION_COMPLETE = '1') then
218
                        -- we are done reading a status register! Going back to idle.
219
                        STATE <= (others => '0');
220
                        SREG_SAMPLE_CLK_local <= '1';
221
 
222
                -- PERIODIC READ BASIC STATUS: LINK
223
                elsif(STATE = 0) and (MI_TRANSACTION_COMPLETE = '1') then
224
                        -- Register 1: basic status (applicable to all: GMII, MII, RGMII)
225
                        STATE <= "1010";
226
                        MI_REGAD <= "10001";
227
                        MI_READ_START <= '1';
228
                elsif(STATE = 10) and (MI_TRANSACTION_COMPLETE = '1') then
229
                        -- we are done reading a status register! Going back to idle.
230
                        STATE <= (others => '0');
231
--                      LINK_STATUS <= MI_RX_DATA(2); commented by KED
232
 
233
                else
234
                        MI_WRITE_START <= '0';
235
                        MI_READ_START <= '0';
236
                        SREG_SAMPLE_CLK_local <= '0';
237
 
238
                end if;
239
        end if;
240
end process;
241
 
242
LINK_STATUS <= '1';--; Added by KED
243
 
244
-- latch status register
245
SREGOUT_001:  process(CLK)
246
begin
247
        if rising_edge(CLK) then
248
                SREG_SAMPLE_CLK <= SREG_SAMPLE_CLK_local;
249
 
250
                if(SREG_SAMPLE_CLK_local = '1') then
251
                        SREG_DATA <= MI_RX_DATA;
252
                end if;
253
        end if;
254
end process;
255
 
256
Inst_MII_MI: MII_MI_V6
257
GENERIC MAP(
258
        PHY_ADDR => PHY_ADDR
259
)
260
PORT MAP(
261
        SYNC_RESET => SYNC_RESET,
262
        CLK => CLK,
263
        MI_REGAD => MI_REGAD,
264
        MI_TX_DATA => MI_TX_DATA,
265
        MI_RX_DATA => MI_RX_DATA,
266
        MI_READ_START => MI_READ_START,
267
        MI_WRITE_START => MI_WRITE_START,
268
        MI_TRANSACTION_COMPLETE => MI_TRANSACTION_COMPLETE,
269
        MCLK => MCLK,
270
        MDI => MDI,
271
        MDO => MDO,
272
        MDT => MDT
273
);
274
 
275
end Behavioral;
276
 

powered by: WebSVN 2.1.0

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