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

Subversion Repositories gbiteth

[/] [gbiteth/] [trunk/] [rtl/] [rgmii/] [rgmii_mdio.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 axuan25268
-------------------------------------------------------------------------------
2
-- Title      : 
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : rgmii_mdio.vhd
6
-- Author     : liyi  <alxiuyain@foxmail.com>
7
-- Company    : OE@HUST
8
-- Created    : 2012-12-02
9
-- Last update: 2012-12-02
10
-- Platform   : 
11
-- Standard   : VHDL'93/02
12
-------------------------------------------------------------------------------
13
-- Description: 
14
-------------------------------------------------------------------------------
15
-- Copyright (c) 2012 OE@HUST
16
-------------------------------------------------------------------------------
17
-- Revisions  :
18
-- Date        Version  Author  Description
19
-- 2012-12-02  1.0      liyi    Created
20
-------------------------------------------------------------------------------
21
LIBRARY ieee;
22
USE ieee.std_logic_1164.ALL;
23
USE ieee.std_logic_unsigned.ALL;
24
-------------------------------------------------------------------------------
25
ENTITY rgmii_mdio IS
26
 
27
  PORT (
28
    iWbClk : IN STD_LOGIC;
29
    iRst_n : IN STD_LOGIC;
30
 
31
    ---------------------------------------------------------------------------
32
    -- signals from register file
33
    ---------------------------------------------------------------------------
34
    iPHYAddr  : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
35
    iRegAddr  : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
36
    iNoPre    : IN STD_LOGIC;
37
    iData2PHY : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
38
    iClkDiv   : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
39
    iRdOp     : IN STD_LOGIC;
40
    iWrOp     : IN STD_LOGIC;
41
 
42
    ---------------------------------------------------------------------------
43
    -- signals to register file
44
    ---------------------------------------------------------------------------
45
    oDataFromPHY      : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);  -- data from PHY registers
46
    oDataFromPHYValid : OUT STD_LOGIC;  -- only valid for 1 clock cycle
47
    oClrRdOp          : OUT STD_LOGIC;  -- only valid for 1 clock cycle
48
    oClrWrOp          : OUT STD_LOGIC;  -- only valid for 1 clock cycle
49
    oMDIOBusy         : OUT STD_LOGIC;  -- manegement is busy
50
 
51
    ---------------------------------------------------------------------------
52
    -- Management interface
53
    ---------------------------------------------------------------------------
54
    iMDI  : IN  STD_LOGIC;
55
    oMDHz : OUT STD_LOGIC;              -- mdio is in HighZ state
56
    oMDC  : OUT STD_LOGIC
57
    );
58
 
59
END ENTITY rgmii_mdio;
60
-------------------------------------------------------------------------------
61
ARCHITECTURE rtl OF rgmii_mdio IS
62
 
63
  SIGNAL rdPend, wrPend : STD_LOGIC;
64
 
65
  SIGNAL endOp : STD_LOGIC;
66
  SIGNAL busy  : STD_LOGIC;
67
 
68
  SIGNAL sendEn    : BOOLEAN;  -- Data is output on sendEn. Delay it slightly from the 
69
  --clock to ensure setup and hold timing is met
70
  SIGNAL receiveEn : BOOLEAN;  -- Sample read data just before rising edge of MDC
71
 
72
BEGIN  -- ARCHITECTURE rtl
73
 
74
  -----------------------------------------------------------------------------
75
  -- receive command from wishbone 
76
  -----------------------------------------------------------------------------
77
  oMDIOBusy <= busy;
78
  busy      <= wrPend OR rdPend;
79
  PROCESS (iWbClk, iRst_n) IS
80
  BEGIN
81
    IF iRst_n = '0' THEN
82
      rdPend        <= '0';
83
      wrPend        <= '0';
84
      oClrWrOp      <= '0';
85
      oClrRdOp      <= '0';
86
    ELSIF rising_edge(iWbClk) THEN
87
      oClrWrOp <= '0';
88
      oClrRdOp <= '0';
89
      IF busy = '0' THEN
90
        IF iRdOp = '1' THEN
91
          rdPend   <= '1';
92
          oClrRdOp <= '1';
93
        ELSIF iWrOp = '1' THEN
94
          wrPend   <= '1';
95
          oClrWrOp <= '1';
96
        END IF;
97
      ELSIF endOp = '1' THEN
98
        rdPend        <= '0';
99
        wrPend        <= '0';
100
      END IF;
101
    END IF;
102
  END PROCESS;
103
 
104
  -----------------------------------------------------------------------------
105
  -- MDC generation
106
  -----------------------------------------------------------------------------
107
  mdcGen : BLOCK IS
108
    SIGNAL mdc       : STD_LOGIC;
109
    SIGNAL mdcClkDiv : INTEGER RANGE 0 TO 127;
110
    SIGNAL clkDivTmp : INTEGER RANGE 0 TO 126;
111
  BEGIN  -- BLOCK mdc
112
    oMDC      <= mdc;
113
    clkDivTmp <= 1 WHEN iClkDiv < 4 ELSE (conv_integer(iClkDiv(7 DOWNTO 1))-1);
114
    sendEn    <= mdc = '1' AND mdcClkDiv = 0;  -- falling edge send
115
    receiveEn <= mdc = '0' AND mdcClkDiv = 0;  -- rising edge receive
116
    PROCESS (iWbClk, iRst_n) IS
117
    BEGIN
118
      IF iRst_n = '0' THEN
119
        mdc       <= '0';
120
        mdcClkDiv <= 0;
121
      ELSIF rising_edge(iWbClk) THEN
122
        IF mdcClkDiv = 0 THEN
123
          mdcClkDiv <= clkDivTmp;
124
          mdc       <= NOT mdc;
125
        ELSE
126
          mdcClkDiv <= mdcClkDiv - 1;
127
        END IF;
128
      END IF;
129
    END PROCESS;
130
  END BLOCK mdcGen;
131
 
132
  operation : BLOCK IS
133
    TYPE state_t IS (PREAMBLE, IDLE, CTRL, WRITE, READ);
134
    SIGNAL state    : state_t;
135
    SIGNAL bitCnt   : INTEGER RANGE 0 TO 31;
136
    SIGNAL shiftReg : STD_LOGIC_VECTOR(15 DOWNTO 0);
137
  BEGIN  -- BLOCK operation
138
    PROCESS (iWbClk, iRst_n) IS
139
    BEGIN
140
      IF iRst_n = '0' THEN
141
        oMDHz             <= '1';
142
        state             <= PREAMBLE;
143
        endOp             <= '0';
144
        bitCnt            <= 0;
145
        shiftReg          <= (OTHERS => '0');
146
        oDataFromPHYValid <= '0';
147
        oDataFromPHY      <= (OTHERS => '0');
148
      ELSIF rising_edge(iWbClk) THEN
149
        endOp             <= '0';
150
        oDataFromPHYValid <= '0';
151
        CASE state IS
152
          WHEN PREAMBLE =>
153
            IF sendEn THEN
154
              bitCnt <= bitCnt + 1;
155
              oMDHz  <= '1';
156
              IF bitCnt = 30 THEN
157
                state <= IDLE;
158
              END IF;
159
            END IF;
160
          WHEN IDLE =>
161
            IF sendEn THEN
162
              IF busy = '1' THEN        -- start transaction
163
                oMDHz    <= '0';        -- firstbit of start word
164
                state    <= CTRL;
165
                bitCnt   <= 0;
166
                shiftReg <= iData2PHY;
167
              END IF;
168
            END IF;
169
          WHEN CTRL =>
170
            IF sendEn THEN
171
              bitCnt <= bitCnt + 1;
172
              CASE bitCnt IS
173
                WHEN 0  => oMDHz <= '1';   -- second bit of start word
174
                --  OPCODE. 1 then 0 for read, 0 then 1 for write
175
                WHEN 1  => oMDHz <= rdPend;
176
                WHEN 2  => oMDHz <= NOT rdPend;
177
                -- PHY address
178
                WHEN 3  => oMDHz <= iPHYAddr(4);
179
                WHEN 4  => oMDHz <= iPHYAddr(3);
180
                WHEN 5  => oMDHz <= iPHYAddr(2);
181
                WHEN 6  => oMDHz <= iPHYAddr(1);
182
                WHEN 7  => oMDHz <= iPHYAddr(0);
183
                --  Register address
184
                WHEN 8  => oMDHz <= iRegAddr(4);
185
                WHEN 9  => oMDHz <= iRegAddr(3);
186
                WHEN 10 => oMDHz <= iRegAddr(2);
187
                WHEN 11 => oMDHz <= iRegAddr(1);
188
                WHEN 12 => oMDHz <= iRegAddr(0);
189
                -- TA
190
                WHEN 13 => oMDHz <= '1';
191
                WHEN 14 =>
192
                  IF rdPend = '0' THEN
193
                    state  <= WRITE;
194
                    oMDHz  <= '0';
195
                    bitCnt <= 0;
196
                  END IF;
197
                WHEN 15 =>
198
                  state  <= READ;
199
                  bitCnt <= 0;
200
                WHEN OTHERS => NULL;
201
              END CASE;
202
            END IF;
203
          WHEN WRITE =>
204
            IF sendEn THEN
205
              oMDHz    <= shiftReg(15);
206
              shiftReg <= shiftReg(14 DOWNTO 0) & '0';
207
              bitCnt   <= bitCnt + 1;
208
              IF bitCnt = 15 THEN
209
                endOp  <= '1';
210
                bitCnt <= 0;
211
                IF iNoPre = '1' THEN
212
                  state <= IDLE;
213
                ELSE
214
                  state <= PREAMBLE;
215
                END IF;
216
              END IF;
217
            END IF;
218
          WHEN READ =>
219
            IF receiveEn THEN
220
              bitCnt   <= bitCnt + 1;
221
              shiftReg <= shiftReg(14 DOWNTO 0) & iMDI;
222
              IF bitCnt = 15 THEN
223
                bitCnt            <= 0;
224
                endOp             <= '1';
225
                oDataFromPHY      <= shiftReg(14 DOWNTO 0) & iMDI;
226
                oDataFromPHYValid <= '1';
227
                IF iNoPre = '1' THEN
228
                  state <= IDLE;
229
                ELSE
230
                  state <= PREAMBLE;
231
                END IF;
232
              END IF;
233
            END IF;
234
          WHEN OTHERS => NULL;
235
        END CASE;
236
      END IF;
237
    END PROCESS;
238
  END BLOCK operation;
239
 
240
END ARCHITECTURE rtl;

powered by: WebSVN 2.1.0

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