OpenCores
URL https://opencores.org/ocsvn/1000base-x/1000base-x/trunk

Subversion Repositories 1000base-x

[/] [1000base-x/] [trunk/] [rtl/] [verilog/] [ge_1000baseX_an.v] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 dwp
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  File name "ge_1000baseX_an.v"                               ////
4
////                                                              ////
5
////  This file is part of the :                                  ////
6
////                                                              ////
7
//// "1000BASE-X IEEE 802.3-2008 Clause 36 - PCS project"         ////
8
////                                                              ////
9
////  http://opencores.org/project,1000base-x                     ////
10
////                                                              ////
11
////  Author(s):                                                  ////
12
////      - D.W.Pegler Cambridge Broadband Networks Ltd           ////
13
////                                                              ////
14
////      { peglerd@gmail.com, dwp@cambridgebroadand.com }        ////
15
////                                                              ////
16
//////////////////////////////////////////////////////////////////////
17
////                                                              ////
18
//// Copyright (C) 2009 AUTHORS. All rights reserved.             ////
19
////                                                              ////
20
//// This source file may be used and distributed without         ////
21
//// restriction provided that this copyright statement is not    ////
22
//// removed from the file and that any derivative work contains  ////
23
//// the original copyright notice and the associated disclaimer. ////
24
////                                                              ////
25
//// This source file is free software; you can redistribute it   ////
26
//// and/or modify it under the terms of the GNU Lesser General   ////
27
//// Public License as published by the Free Software Foundation; ////
28
//// either version 2.1 of the License, or (at your option) any   ////
29
//// later version.                                               ////
30
////                                                              ////
31
//// This source is distributed in the hope that it will be       ////
32
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
33
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
34
//// PURPOSE.  See the GNU Lesser General Public License for more ////
35
//// details.                                                     ////
36
////                                                              ////
37
//// You should have received a copy of the GNU Lesser General    ////
38
//// Public License along with this source; if not, download it   ////
39
//// from http://www.opencores.org/lgpl.shtml                     ////
40
////                                                              ////
41
//////////////////////////////////////////////////////////////////////
42
////                                                              ////
43
//// This module is based on the coding method described in       ////
44
//// IEEE Std 802.3-2008 Clause 37" Auto-Negotiation function,    ////
45
//// type 1000BASE-X"; see :                                      ////
46
////                                                              ////
47
//// http://standards.ieee.org/about/get/802/802.3.html           ////
48
//// and                                                          ////
49
//// doc/802.3-2008_section3.pdf, Clause 37.                      ////
50
////                                                              ////
51
//////////////////////////////////////////////////////////////////////
52
 
53
 
54
`include "ge_1000baseX_constants.v"
55
`include "timescale.v"
56
 
57
module ge_1000baseX_an (
58
 
59
   // --- clocks and reset ---
60
   input               ck,
61
   input               reset,
62
 
63
   // --- Startup interface. ---
64
   input               startup_enable,
65
 
66
   // --- Auto-negotiation ctrl parameter ---
67
   output reg [2:0]    xmit,
68
   output reg [15:0]   tx_config,
69
   input      [15:0]   rx_config,
70
   input               rx_config_set,
71
   input               ability_match,
72
   input               acknowledge_match,
73
   input               consistency_match,
74
   input               idle_match,
75
 
76
   // --- RX_UNITDATA.indicate messages from RX state machine ---
77
   input      [2:0]    rudi,
78
 
79
 
80
   // --- Synchronisation Status ---
81
   input               sync_status,
82
   input               signal_detect,
83
 
84
   // --- GMII Register 0 - AN Basic Control register ---
85
   input               mr_main_reset,
86
   input               mr_loopback,
87
   input               mr_restart_an,
88
   input               mr_an_enable,
89
 
90
   // --- GMII Register 1 - AN Basic Status register ---                    
91
   output reg          mr_an_complete,
92
 
93
   // --- GMII register 4 - AN Advertisement                
94
   input [15:0]         mr_adv_ability,
95
 
96
   // --- GMII register 5 - AN Link Partner Ability
97
   output reg [15:0]     mr_lp_adv_ability,
98
 
99
   // --- GMII register 6 - AN Expansion
100
   output reg           mr_np_abl,
101
   output reg           mr_page_rx,
102
 
103
   // --- GMII register 7 - AN Next Page
104
   input [15:0]         mr_np_tx,
105
 
106
   // --- GMII register 8 - AN Link Partner Next Page
107
   output reg [15:0]    mr_lp_np_rx
108
 );
109
 
110
   //////////////////////////////////////////////////////////////////////////////
111
   //
112
   //////////////////////////////////////////////////////////////////////////////
113
 
114
   reg                  mr_np_loaded;
115
 
116
   //////////////////////////////////////////////////////////////////////////////
117
   //
118
   //////////////////////////////////////////////////////////////////////////////
119
 
120
`ifdef MODEL_TECH
121
  enum logic [3:0] {
122
`else
123
  localparam
124
`endif
125
                    S_PCS_AN_STARTUP_RUN          = 0,
126
                    S_PCS_AN_ENABLE               = 1,
127
                    S_PCS_AN_RESTART              = 2,
128
                    S_PCS_AN_DISABLE_LINK_OK      = 3,
129
                    S_PCS_AN_ABILITY_DETECT       = 4,
130
                    S_PCS_AN_ACKNOWLEDGE_DETECT   = 5,
131
                    S_PCS_AN_COMPLETE_ACKNOWLEDGE = 6,
132
                    S_PCS_AN_IDLE_DETECT          = 7,
133
                    S_PCS_AN_LINK_OK              = 8,
134
                    S_PCS_AN_NEXT_PAGE_WAIT       = 9
135
`ifdef MODEL_TECH
136
  } pcs_an_present, pcs_an_next;
137
`else
138
   ; reg [3:0] pcs_an_present, pcs_an_next;
139
`endif
140
 
141
   //////////////////////////////////////////////////////////////////////////////
142
   // rx configuration
143
   //////////////////////////////////////////////////////////////////////////////
144
 
145
   wire rx_config_clr = ~rx_config_set;
146
 
147
   //////////////////////////////////////////////////////////////////////////////
148
   //  Link timer
149
   //////////////////////////////////////////////////////////////////////////////  
150
 
151
`ifdef MODEL_TECH
152
`define LINK_TIMER_DONE 1250
153
`else
154
`define LINK_TIMER_DONE 1250000
155
`endif
156
 
157
   reg [20:0] link_timer_cnt;
158
   reg        link_timer_m_start, link_timer_m_inc;
159
   wire       link_timer_done;
160
 
161
   always @(posedge ck, posedge reset)
162
    if (reset)
163
      begin
164
         link_timer_cnt <= 0;
165
      end
166
    else
167
      begin
168
         if      (link_timer_m_start) link_timer_cnt <= 0;
169
         else if (link_timer_m_inc) link_timer_cnt <= link_timer_cnt + 1;
170
      end
171
 
172
      assign link_timer_done = (link_timer_cnt >= `LINK_TIMER_DONE);
173
 
174
   //////////////////////////////////////////////////////////////////////////////
175
   // xmit -  set to tell TX state machine state of AN
176
   //////////////////////////////////////////////////////////////////////////////
177
 
178
   reg      xmit_CONFIGURATION_m_set, xmit_DATA_m_set, xmit_IDLE_m_set;
179
 
180
   always @(posedge ck, posedge reset)
181
     if (reset)
182
       xmit <= `XMIT_IDLE;
183
     else
184
       begin
185
          if      (~mr_an_enable & rudi != `RUDI_INVALID) xmit <= `XMIT_DATA;
186
          else if (xmit_CONFIGURATION_m_set)              xmit <= `XMIT_CONFIGURATION;
187
          else if (xmit_DATA_m_set)                       xmit <= `XMIT_DATA;
188
          else if (xmit_IDLE_m_set)                       xmit <= `XMIT_IDLE;
189
       end
190
 
191
   //////////////////////////////////////////////////////////////////////////////
192
   //  mr_lp_adv_ability - variable to store Link partner capabilities
193
   //////////////////////////////////////////////////////////////////////////////
194
 
195
   reg      mr_lp_adv_ability_set, mr_lp_adv_ability_clr;
196
 
197
     always @(posedge ck, posedge reset)
198
       if (reset)
199
         mr_lp_adv_ability <= 16'h0;
200
       else
201
         begin
202
            if      (mr_lp_adv_ability_set) mr_lp_adv_ability <= rx_config;
203
            else if (mr_lp_adv_ability_clr) mr_lp_adv_ability <= 16'h00;
204
         end
205
 
206
   //////////////////////////////////////////////////////////////////////////////
207
   //  mr_np_loaded - variable to indicate if the next page has been loaded
208
   //////////////////////////////////////////////////////////////////////////////   
209
 
210
   reg      mr_np_loaded_m_set, mr_np_loaded_m_clr;
211
 
212
    always @(posedge ck, posedge reset)
213
     if (reset)
214
       mr_np_loaded <= 0;
215
     else
216
       begin
217
          if       (mr_np_loaded_m_set) mr_np_loaded <= 1;
218
          else if  (mr_np_loaded_m_clr) mr_np_loaded <= 0;
219
       end
220
 
221
   //////////////////////////////////////////////////////////////////////////////
222
   // mr_page_rx_m_clr 
223
   //////////////////////////////////////////////////////////////////////////////  
224
 
225
   reg      mr_page_rx_m_set, mr_page_rx_m_clr;
226
 
227
   always @(posedge ck, posedge reset)
228
    if (reset)
229
      mr_page_rx <= 0;
230
    else
231
      begin
232
         if       (mr_page_rx_m_set) mr_page_rx <= 1;
233
         else if  (mr_page_rx_m_clr) mr_page_rx <= 0;
234
      end
235
 
236
   //////////////////////////////////////////////////////////////////////////////
237
   //  mr_an_complete
238
   //////////////////////////////////////////////////////////////////////////////
239
 
240
   reg       mr_an_complete_m_set, mr_an_complete_m_clr;
241
 
242
   always @(posedge ck, posedge reset)
243
     if (reset)
244
        mr_an_complete <= 0;
245
     else
246
       begin
247
          if      (mr_an_complete_m_set) mr_an_complete <= 1;
248
          else if (mr_an_complete_m_clr) mr_an_complete <= 0;
249
       end
250
 
251
   //////////////////////////////////////////////////////////////////////////////
252
   // toggle_tx
253
   //////////////////////////////////////////////////////////////////////////////
254
 
255
   reg toggle_tx, toggle_tx_adv_m_set, toggle_tx_toggle_m_set;
256
 
257
   always @(posedge ck, posedge reset)
258
     if (reset)
259
       toggle_tx <= 0;
260
     else
261
       begin
262
          if      (toggle_tx_adv_m_set)    toggle_tx <= mr_adv_ability[12];
263
          else if (toggle_tx_toggle_m_set) toggle_tx <= ~toggle_tx;
264
       end
265
 
266
   //////////////////////////////////////////////////////////////////////////////
267
   // toggle_rx
268
   //////////////////////////////////////////////////////////////////////////////   
269
 
270
   reg toggle_rx, toggle_rx_m_set;
271
 
272
   always @(posedge ck, posedge reset)
273
     if (reset)
274
       toggle_rx <= 0;
275
     else
276
       begin
277
          if (toggle_rx_m_set) toggle_rx <= rx_config[11];
278
       end
279
 
280
   //////////////////////////////////////////////////////////////////////////////
281
   // tx_config register ctrl
282
   //////////////////////////////////////////////////////////////////////////////  
283
 
284
   reg      tx_config_m_clr, tx_config_ABILITY_m_set, tx_config_ACK_m_set, tx_config_NP_m_set;
285
 
286
   always @(posedge ck, posedge reset)
287
     if (reset)
288
       tx_config <= 0;
289
     else
290
       begin
291
          if      (tx_config_m_clr)         tx_config     <= 0;
292
          else if (tx_config_ACK_m_set)     tx_config[14] <= 1;
293
          else if (tx_config_ABILITY_m_set) tx_config     <= { mr_adv_ability[15],1'b0, mr_adv_ability[13:0]                          };
294
          else if (tx_config_NP_m_set)      tx_config     <= { mr_np_tx[15],      1'b0, mr_np_tx[13:12],     toggle_tx,mr_np_tx[10:0] };
295
       end
296
 
297
   //////////////////////////////////////////////////////////////////////////////
298
   // np_rx
299
   //////////////////////////////////////////////////////////////////////////////
300
 
301
   reg  np_rx, np_rx_m_set;
302
 
303
    always @(posedge ck, posedge reset)
304
      if (reset)
305
        np_rx <= 0;
306
      else
307
        begin
308
           if (np_rx_m_set) np_rx <= rx_config[15];
309
        end
310
 
311
   //////////////////////////////////////////////////////////////////////////////
312
   //  mr_lp_np_rx
313
   //////////////////////////////////////////////////////////////////////////////   
314
 
315
   reg  mr_lp_np_rx_m_set;
316
 
317
    always @(posedge ck, posedge reset)
318
      if (reset)
319
        mr_lp_np_rx <= 0;
320
      else
321
        begin
322
           if (mr_lp_np_rx_m_set) mr_lp_np_rx <= rx_config[15];
323
        end
324
 
325
   //////////////////////////////////////////////////////////////////////////////
326
   // np_page_rx
327
   //////////////////////////////////////////////////////////////////////////////
328
 
329
   reg        np_page_rx, np_page_rx_m_set;
330
 
331
   always @(posedge ck, posedge reset)
332
     if (reset)
333
       np_page_rx <= 0;
334
     else
335
       begin
336
          if (np_page_rx_m_set) np_page_rx <= 1;
337
       end
338
 
339
   //////////////////////////////////////////////////////////////////////////////
340
   // resolve_priority
341
   //////////////////////////////////////////////////////////////////////////////
342
 
343
   reg        resolve_priority, resolve_priority_m_set;
344
 
345
   always @(posedge ck, posedge reset)
346
     if (reset)
347
       resolve_priority <= 0;
348
     else
349
       begin
350
          if (resolve_priority_m_set) resolve_priority <= 1;
351
       end
352
 
353
   //////////////////////////////////////////////////////////////////////////////
354
   // autonegotiation state machine registered part
355
   //////////////////////////////////////////////////////////////////////////////    
356
 
357
   always @(posedge ck, posedge reset)
358
 
359
     pcs_an_present <= (reset) ? S_PCS_AN_STARTUP_RUN :  pcs_an_next;
360
 
361
   //////////////////////////////////////////////////////////////////////////////
362
   // autonegotiation state machine - IEEE 802.3-2008 Clause 36
363
   //////////////////////////////////////////////////////////////////////////////
364
 
365
   always @*
366
     begin
367
        pcs_an_next = pcs_an_present;
368
 
369
        xmit_CONFIGURATION_m_set = 0; xmit_DATA_m_set = 0; xmit_IDLE_m_set = 0;
370
 
371
        mr_np_loaded_m_set = 0; mr_np_loaded_m_clr = 0;
372
 
373
        mr_page_rx_m_set = 0;  mr_page_rx_m_clr = 0;
374
 
375
        mr_an_complete_m_set = 0;  mr_an_complete_m_clr = 0;
376
 
377
        mr_lp_adv_ability_set = 0;  mr_lp_adv_ability_clr = 0;
378
 
379
        tx_config_m_clr = 0; tx_config_ABILITY_m_set = 0;tx_config_ACK_m_set = 0;tx_config_NP_m_set = 0;
380
 
381
        link_timer_m_start = 0; link_timer_m_inc = 0;
382
 
383
        toggle_tx_adv_m_set = 0; toggle_tx_toggle_m_set = 0;
384
 
385
        toggle_rx_m_set = 0; mr_lp_np_rx_m_set = 0; np_rx_m_set = 0; np_page_rx_m_set = 0;
386
 
387
        resolve_priority_m_set = 0;
388
 
389
        case (pcs_an_present)
390
 
391
          S_PCS_AN_STARTUP_RUN:
392
            begin
393
               pcs_an_next = startup_enable ? S_PCS_AN_ENABLE: S_PCS_AN_STARTUP_RUN;
394
            end
395
 
396
 
397
          S_PCS_AN_ENABLE:
398
            begin
399
               mr_page_rx_m_clr = 1;  mr_lp_adv_ability_clr = 1; mr_an_complete_m_clr = 1;
400
 
401
               if (mr_an_enable)
402
                 begin
403
                    xmit_CONFIGURATION_m_set = 1; tx_config_m_clr = 1;
404
                 end
405
               else xmit_IDLE_m_set = 1;
406
 
407
               pcs_an_next = (mr_an_enable) ? S_PCS_AN_RESTART  : S_PCS_AN_DISABLE_LINK_OK;
408
 
409
               link_timer_m_start = mr_an_enable;
410
            end
411
 
412
          S_PCS_AN_RESTART:
413
            begin
414
               mr_np_loaded_m_clr = 1; tx_config_m_clr = 1; xmit_CONFIGURATION_m_set = 1;
415
 
416
               pcs_an_next = (link_timer_done) ? S_PCS_AN_ABILITY_DETECT : S_PCS_AN_RESTART;
417
 
418
               link_timer_m_inc = ~link_timer_done;
419
            end
420
 
421
          S_PCS_AN_DISABLE_LINK_OK:
422
            begin
423
               xmit_DATA_m_set = 1;
424
 
425
               pcs_an_next = S_PCS_AN_DISABLE_LINK_OK;
426
             end
427
 
428
          S_PCS_AN_ABILITY_DETECT:
429
            begin
430
               toggle_tx_adv_m_set = 1; tx_config_ABILITY_m_set = 1;
431
 
432
               pcs_an_next = (ability_match & rx_config_set) ? S_PCS_AN_ACKNOWLEDGE_DETECT : S_PCS_AN_ABILITY_DETECT;
433
 
434
               mr_lp_adv_ability_set = (ability_match & rx_config_set);
435
 
436
            end
437
 
438
          S_PCS_AN_ACKNOWLEDGE_DETECT:
439
            begin
440
               tx_config_ACK_m_set = 1;
441
 
442
               pcs_an_next = (acknowledge_match & consistency_match)  ? S_PCS_AN_COMPLETE_ACKNOWLEDGE :
443
                             (acknowledge_match & ~consistency_match) ? S_PCS_AN_ENABLE               :
444
                             (ability_match & rx_config_clr)          ? S_PCS_AN_ENABLE               : S_PCS_AN_ACKNOWLEDGE_DETECT;
445
 
446
               link_timer_m_start = (acknowledge_match & consistency_match);
447
            end
448
 
449
          S_PCS_AN_COMPLETE_ACKNOWLEDGE:
450
            begin
451
               toggle_tx_toggle_m_set = 1; toggle_rx_m_set = 1; np_rx_m_set = 1; mr_page_rx_m_set = 1;
452
 
453
               if (ability_match & rx_config_clr)  pcs_an_next = S_PCS_AN_ENABLE;
454
 
455
               else if (link_timer_done & (~ability_match | rx_config_set))
456
                 begin
457
                    link_timer_m_start = 1;  pcs_an_next = S_PCS_AN_IDLE_DETECT;
458
                 end
459
 
460
               else link_timer_m_inc = ~link_timer_done;
461
            end
462
 
463
          S_PCS_AN_IDLE_DETECT:
464
            begin
465
               xmit_IDLE_m_set = 1; resolve_priority_m_set = 1;
466
 
467
               pcs_an_next = (ability_match & rx_config_clr) ? S_PCS_AN_ENABLE :
468
                             (idle_match & link_timer_done)  ? S_PCS_AN_LINK_OK : S_PCS_AN_IDLE_DETECT;
469
 
470
               link_timer_m_inc = ~link_timer_done;
471
            end
472
 
473
          S_PCS_AN_LINK_OK:
474
            begin
475
               xmit_DATA_m_set = 1; mr_an_complete_m_set = 1; resolve_priority_m_set = 1;
476
 
477
               pcs_an_next = (ability_match | mr_restart_an) ? S_PCS_AN_ENABLE : S_PCS_AN_LINK_OK;
478
            end
479
        endcase
480
 
481
        if      (~sync_status)          pcs_an_next = S_PCS_AN_ENABLE;
482
        else if (mr_main_reset)         pcs_an_next = S_PCS_AN_ENABLE;
483
        else if (mr_restart_an)         pcs_an_next = S_PCS_AN_ENABLE;
484
        else if (rudi == `RUDI_INVALID) pcs_an_next = S_PCS_AN_ENABLE;
485
     end
486
 
487
endmodule

powered by: WebSVN 2.1.0

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