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

Subversion Repositories gigabit_udp_mac

[/] [gigabit_udp_mac/] [trunk/] [MAC/] [MII_MI _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:  MII_MI_V5.VHD
3
--      Version: 1
4
--      Date last modified: 1-30-11
5
-- Inheritance:         MII_MI.VHD rev1 1-30-11 
6
--
7
-- description:  MII management interface.
8
-- Writes and read registers to/from the PHY IC through 
9
-- the MDC & MDIO serial interface.
10
-- The MCLK clock speed is set as a constant within (integer division of the reference clock CLK).
11
-- USAGE: adjust the constant MCLK_COUNTER_DIV within to meet the MDC/MDIO timing requirements (see PHY specs).
12
-- Virtex-5 use.
13
---------------------------------------------------------------
14
library IEEE;
15
use IEEE.STD_LOGIC_1164.ALL;
16
use IEEE.STD_LOGIC_ARITH.ALL;
17
use IEEE.STD_LOGIC_UNSIGNED.ALL;
18
 
19
entity MII_MI_V6 is
20
        generic (
21
                PHY_ADDR: std_logic_vector(4 downto 0)
22
                        -- PHY Address
23
        );
24
    Port (
25
                --// CLK, RESET
26
                SYNC_RESET: in std_logic;
27
                CLK: in std_logic;
28
 
29
                MI_REGAD: in std_logic_vector(4 downto 0);
30
                        -- 32 register address space for the PHY (ieee 802.3)
31
                        --  0 - 15 are standard PHY registers as per IEEE specification.
32
                        -- 16 - 31 are vendor-specific registers
33
                MI_TX_DATA: in std_logic_vector(15 downto 0);
34
                MI_RX_DATA: out std_logic_vector(15 downto 0);
35
                MI_READ_START: in std_logic;
36
                        -- 1 CLK wide pulse to start read transaction
37
                        -- will be ignored if the previous transaction is yet to be completed.
38
                        -- For reliable operation, the user must check MI_TRANSACTION_COMPLETE first.
39
                MI_WRITE_START: in std_logic;
40
                        -- 1 CLK wide pulse to start write transaction
41
                        -- will be ignored if the previous transaction is yet to be completed.
42
                        -- For reliable operation, the user must check MI_TRANSACTION_COMPLETE first.
43
 
44
                MI_TRANSACTION_COMPLETE: out std_logic;
45
                        -- '1' when transaction is complete 
46
 
47
                --// serial interface. connect to PHY 
48
                MCLK: out std_logic;
49
                MDI: in std_logic;  -- MDIO input
50
                MDO: out std_logic;  -- MDIO output
51
                MDT: out std_logic  -- MDIO tri-state
52
 
53
 );
54
end entity;
55
 
56
architecture Behavioral of MII_MI_V6 is
57
--------------------------------------------------------
58
--      COMPONENTS
59
--------------------------------------------------------
60
--------------------------------------------------------
61
--     SIGNALS
62
--------------------------------------------------------
63
signal STATE: std_logic_vector(7 downto 0) := x"00";   -- 0 is idle
64
signal TXRX_FRAME: std_logic_vector(63 downto 0); --32-bit idle sequence + 32-bit MI serial port frame + 2 end bit
65
signal MCLK_LOCAL: std_logic := '0';
66
signal MCLK_LOCAL_D: std_logic := '0';
67
signal MDOE: std_logic := '1';
68
signal MDI_DATA: std_logic := '0';
69
signal MDI_SAMPLE_CLK: std_logic := '0';
70
constant MCLK_COUNTER_DIV: std_logic_vector(7 downto 0) := x"17";
71
        -- divide CLK by this 2*(value + 1) to generate a slower MCLK
72
        -- MCLK period (typ): 400 ns [Micrel KSZ9021]
73
        -- Example: 120 MHz clock, 400ns MCLK period => MCLK_COUNTER_DIV = 23
74
signal MCLK_COUNTER: std_logic_vector(7 downto 0) := x"00";
75
signal MI_SAMPLE_REQ: std_logic;
76
 
77
--------------------------------------------------------
78
--      IMPLEMENTATION
79
--------------------------------------------------------
80
begin
81
 
82
------------------------------------------------------
83
-- MCLK GENERATION
84
------------------------------------------------------
85
-- Divide CLK by MCLK_COUNTER_DIV
86
MCLK_GEN_001: process(CLK)
87
begin
88
        if rising_edge(CLK) then
89
                if(SYNC_RESET = '1') then
90
                        MCLK_COUNTER <= (others => '0');
91
                        MI_SAMPLE_REQ <= '0';
92
                elsif(STATE = 0) then
93
                        -- idle. awaiting a start of transaction.
94
                        MI_SAMPLE_REQ <= '0';
95
                        if(MI_WRITE_START = '1') or (MI_READ_START = '1') then
96
                                -- get started. reset MCLK phase.
97
                                MCLK_COUNTER <= (others => '0');
98
                        end if;
99
                else
100
                        -- read/write transaction in progress
101
                        if(MCLK_COUNTER = MCLK_COUNTER_DIV) then
102
                                -- next sample
103
                                MI_SAMPLE_REQ <= '1';
104
                                MCLK_COUNTER <= (others => '0');
105
                        else
106
                                MI_SAMPLE_REQ <= '0';
107
                                MCLK_COUNTER <= MCLK_COUNTER + 1;
108
                        end if;
109
                end if;
110
        end if;
111
end process;
112
 
113
------------------------------------------------------
114
-- OUTPUT TO PHY
115
------------------------------------------------------
116
 
117
STATE_GEN_001: process(CLK)
118
begin
119
        if rising_edge(CLK) then
120
                if(SYNC_RESET = '1') then
121
                        STATE <= (others => '0');
122
                        MCLK_LOCAL <= '0';
123
                        MDOE <= '0';
124
                elsif(STATE = 0) then
125
                        if (MI_WRITE_START = '1') then
126
                                -- was idle. start of write transaction. start counting 
127
                                STATE <= x"01";
128
                                MCLK_LOCAL <= '0';
129
                                MDOE <= '1';
130
                        elsif (MI_READ_START = '1') then
131
                                -- was idle. start of read transaction. start counting 
132
                                STATE <= x"81";
133
                                MCLK_LOCAL <= '0';
134
                                MDOE <= '1';
135
                        end if;
136
                elsif (MI_SAMPLE_REQ = '1') then
137
                        if (STATE = 128) then
138
                                -- write transaction complete. set output enable to high impedance
139
                                STATE <= x"00";
140
                                MCLK_LOCAL <= '0';
141
                                MDOE <= '0';
142
                        elsif (STATE = 220) then
143
                                -- read transaction: finished writing addresses. switch to read mode
144
                                STATE <= STATE + 1;
145
                                MCLK_LOCAL <= not MCLK_LOCAL;
146
                                MDOE <= '0';
147
                        elsif (STATE = 255) then
148
                                -- read transaction complete. reset state.
149
                                STATE <= x"00";
150
                                MCLK_LOCAL <= '0';
151
                                MI_RX_DATA <= TXRX_FRAME(15 downto 0);  -- complete word read from PHY
152
                        else
153
                                STATE <= STATE + 1;
154
                                MCLK_LOCAL <= not MCLK_LOCAL;
155
                        end if;
156
                end if;
157
        end if;
158
end process;
159
 
160
-- immediate turn off the 'available' message as soon as a new transaction is triggered.
161
MI_TRANSACTION_COMPLETE <= '0' when (STATE > 0) else
162
                                                                        '0' when (MI_WRITE_START = '1') else
163
                                                                        '0' when (MI_READ_START = '1') else
164
                                                                        '1';
165
 
166
-- send MCLK to output
167
MCLK <= MCLK_LOCAL;
168
 
169
TXRX_FRAME_GEN: process(CLK)
170
begin
171
        if rising_edge(CLK) then
172
                if(SYNC_RESET = '1') then
173
                        TXRX_FRAME <= (others => '0');
174
                elsif(MI_WRITE_START = '1') then
175
                        -- start of write transaction. 
176
                        -- Note: transmission sequence starts at bit 63 
177
                        TXRX_FRAME(63 downto 32) <= x"FFFFFFFF";        -- preamble: idle sequence 32 '1's
178
                        TXRX_FRAME(31 downto 23)  <= "0101" & PHY_ADDR;
179
                        TXRX_FRAME(22 downto 18) <= MI_REGAD;
180
                        TXRX_FRAME(17 downto 16) <= "10";
181
                        TXRX_FRAME(15 downto 0) <= MI_TX_DATA;
182
                elsif(MI_READ_START = '1') then
183
                        -- start of read transaction. 
184
                        -- Note: transmission sequence starts at bit 63 
185
                        TXRX_FRAME(63 downto 32) <= x"FFFFFFFF";        -- preamble: idle sequence 32 '1's
186
                        TXRX_FRAME(31 downto 23)  <= "0110" & PHY_ADDR;
187
                        TXRX_FRAME(22 downto 18) <= MI_REGAD;
188
                elsif(MI_SAMPLE_REQ = '1') and (STATE /= 0) and (STATE(0) = '0') and (MDOE = '1') then
189
                        -- shift TXRX_FRAME 1 bit left every two clocks
190
                        TXRX_FRAME(63 downto 1) <= TXRX_FRAME(62 downto 0);
191
                elsif(MDI_SAMPLE_CLK = '1') and (STATE /= 0) and (STATE(0) = '1') and (MDOE = '0') then
192
                        -- shift MDIO into TXRX_FRAME 1 bit left every two clocks (read at the falling edge of MCLK)
193
                        -- do this 16 times to collect the 16-bit response from the PHY.
194
                        TXRX_FRAME(63 downto 1) <= TXRX_FRAME(62 downto 0);
195
                        TXRX_FRAME(0) <= MDI_DATA;
196
                end if;
197
  end if;
198
end process;
199
 
200
-- select output bit. 
201
MDO <= TXRX_FRAME(63);
202
MDT <= not MDOE;
203
 
204
------------------------------------------------------
205
-- INPUT FROM PHY
206
------------------------------------------------------
207
 
208
 
209
-- reclock MDI input at the falling edge of MCLK
210
RX_RECLOCK_001: process(CLK)
211
begin
212
        if rising_edge(CLK) then
213
                MCLK_LOCAL_D <= MCLK_LOCAL;
214
 
215
                if(MCLK_LOCAL = '0') and (MCLK_LOCAL_D = '1') then
216
                        MDI_DATA <= MDI;
217
                        MDI_SAMPLE_CLK <= '1';
218
                else
219
                        MDI_SAMPLE_CLK <= '0';
220
                end if;
221
        end if;
222
end process;
223
 
224
 
225
end Behavioral;

powered by: WebSVN 2.1.0

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