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

Subversion Repositories 1000base-x

[/] [1000base-x/] [trunk/] [rtl/] [verilog/] [ge_1000baseX_rx.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_rx.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 36 "Physical Coding Sublayer(PCS) ////
45
//// and Physical Medium Attachment (PMA) sublayer, type          ////
46
//// 1000BASE-X"; see :                                           ////
47
////                                                              ////
48
//// http://standards.ieee.org/about/get/802/802.3.html           ////
49
//// and                                                          ////
50
//// doc/802.3-2008_section3.pdf, Clause/Section 36.              ////
51
////                                                              ////
52
//////////////////////////////////////////////////////////////////////
53
 
54
`include "timescale.v"
55
 
56
`include "ge_1000baseX_regs.v"
57
`include "ge_1000baseX_constants.v"
58
 
59
module ge_1000baseX_rx(
60
 
61
   // Receive clock and reset 
62
   input               ck,
63
   input               reset,
64
 
65
   // Receive 8B bus from 8b10 decoder 
66
   input [7:0]          ebi_rxd,
67
 
68
   input               ebi_K,
69
   input               rx_even,
70
   input               carrier_detect,
71
 
72
   // Receive sync status 
73
   input              sync_status,
74
   input              signal_detect,
75
 
76
   // Frame receive pulse       
77
   output              rx_frame_pulse,
78
 
79
   // Receive GMII bus 
80
   output reg  [7:0]   gmii_rxd,
81
   output reg          gmii_rx_dv,
82
   output reg          gmii_rx_er,
83
 
84
   output reg          receiving,
85
 
86
   // Auto-negotiation ctrl 
87
   input      [2:0]    xmit,
88
   output reg [15:0]   rx_config,
89
   output reg          rx_config_set,
90
   input               mr_main_reset,
91
   output reg [2:0]    rudi,
92
 
93
   output reg          ability_match,
94
   output reg          acknowledge_match,
95
 
96
   output              consistency_match,
97
   output              idle_match
98
);
99
 
100
   //////////////////////////////////////////////////////////////////////////////
101
   //  Diagnostics registers
102
   //////////////////////////////////////////////////////////////////////////////
103
 
104
`define RX_FRAME_CNT            16'h0000
105
`define RX_DATA_CNT             16'h0001
106
`define EARLY_END_CNT           16'h0002
107
`define CHECK_END_T_R_K28_5_CNT 16'h0003
108
`define CHECK_END_R_R_K28_5_CNT 16'h0004
109
`define CHECK_END_T_R_R_CNT     16'h0005
110
`define CHECK_END_R_R_R_CNT     16'h0006
111
`define CHECK_END_R_R_S_CNT     16'h0007
112
`define RESET                   16'hffff
113
 
114
   reg [7:0]            ge_x_pcs_rx_stats_inc;
115
 
116
   reg [15:0]           rx_frame_cnt;
117
   reg [15:0]           rx_data_cnt;
118
   reg [15:0]           early_end_cnt;
119
   reg [15:0]           check_end_T_R_K28_5_cnt;
120
   reg [15:0]           check_end_R_R_K28_5_cnt;
121
   reg [15:0]           check_end_T_R_R_cnt;
122
   reg [15:0]           check_end_R_R_R_cnt;
123
   reg [15:0]           check_end_R_R_S_cnt;
124
 
125
   always @(posedge ck, posedge reset)
126
 
127
     if (reset)
128
       begin
129
          rx_frame_cnt            <= 0; rx_data_cnt             <= 0;
130
          early_end_cnt           <= 0; check_end_T_R_K28_5_cnt <= 0;
131
          check_end_R_R_K28_5_cnt <= 0; check_end_T_R_R_cnt     <= 0;
132
          check_end_R_R_R_cnt     <= 0; check_end_R_R_S_cnt     <= 0;
133
       end
134
     else
135
       begin
136
          if      (ge_x_pcs_rx_stats_inc[0]) rx_frame_cnt            <= rx_frame_cnt + 1;
137
          else if (ge_x_pcs_rx_stats_inc[1]) rx_data_cnt             <= rx_data_cnt + 1;
138
          else if (ge_x_pcs_rx_stats_inc[2]) early_end_cnt           <= early_end_cnt + 1;
139
          else if (ge_x_pcs_rx_stats_inc[3]) check_end_T_R_K28_5_cnt <= check_end_T_R_K28_5_cnt + 1;
140
          else if (ge_x_pcs_rx_stats_inc[4]) check_end_R_R_K28_5_cnt <= check_end_R_R_K28_5_cnt + 1;
141
          else if (ge_x_pcs_rx_stats_inc[5]) check_end_T_R_R_cnt     <= check_end_T_R_R_cnt + 1;
142
          else if (ge_x_pcs_rx_stats_inc[6]) check_end_R_R_R_cnt     <= check_end_R_R_R_cnt + 1;
143
          else if (ge_x_pcs_rx_stats_inc[7]) check_end_R_R_S_cnt     <= check_end_R_R_S_cnt + 1;
144
       end
145
 
146
   //////////////////////////////////////////////////////////////////////////////
147
   //
148
   ////////////////////////////////////////////////////////////////////////////// 
149
 
150
   assign            rx_frame_pulse = ge_x_pcs_rx_stats_inc[0];
151
 
152
   //////////////////////////////////////////////////////////////////////////////
153
   // Soft reset
154
   //////////////////////////////////////////////////////////////////////////////  
155
 
156
   reg               soft_reset;
157
 
158
   always @(posedge ck, posedge reset)
159
     if (reset)
160
       soft_reset <= 0;
161
     else
162
       soft_reset <= mr_main_reset;
163
 
164
   //////////////////////////////////////////////////////////////////////////////
165
   // When Decoding EPDs (End_Of_Packet Delimiter) the RX state machine needs
166
   // to compare the current code-group to the two code-groups that follow it.
167
   //////////////////////////////////////////////////////////////////////////////   
168
 
169
   reg [7:0]            ebi_rxd_d1;
170
   reg [7:0]            ebi_rxd_d2;
171
   reg [7:0]            ebi_rxd_d3;
172
 
173
   reg                 ebi_K_d1,          ebi_K_d2,          ebi_K_d3;
174
   reg                 rx_even_d1,        rx_even_d2,        rx_even_d3;
175
   reg                 sync_status_d1,    sync_status_d2,    sync_status_d3;
176
   reg                 carrier_detect_d1, carrier_detect_d2, carrier_detect_d3;
177
 
178
   always @(posedge ck, posedge reset)
179
     if (reset)
180
       begin
181
          ebi_K_d1          <= 0; ebi_K_d2          <= 0; ebi_K_d3          <= 0;
182
          rx_even_d1        <= 0; rx_even_d2        <= 0; rx_even_d3        <= 0;
183
          ebi_rxd_d1        <= 0; ebi_rxd_d2        <= 0; ebi_rxd_d3        <= 0;
184
          sync_status_d1    <= 0; sync_status_d2    <= 0; sync_status_d3    <= 0;
185
          carrier_detect_d1 <= 0; carrier_detect_d2 <= 0; carrier_detect_d3 <= 0;
186
       end
187
     else
188
       begin
189
          ebi_K_d3          <= ebi_K_d2;           ebi_K_d2          <= ebi_K_d1;          ebi_K_d1          <= ebi_K;
190
          rx_even_d3        <= rx_even_d2;         rx_even_d2        <= rx_even_d1;        rx_even_d1        <= rx_even;
191
          ebi_rxd_d3        <= ebi_rxd_d2;         ebi_rxd_d2        <= ebi_rxd_d1;        ebi_rxd_d1        <= ebi_rxd;
192
          sync_status_d3    <= sync_status_d2;     sync_status_d2    <= sync_status_d1;    sync_status_d1    <= sync_status;
193
          carrier_detect_d3 <= carrier_detect_d2;  carrier_detect_d2 <= carrier_detect_d1; carrier_detect_d1 <= carrier_detect;
194
       end
195
 
196
 
197
`ifdef MODEL_TECH
198
   wire [4:0] ebi_rxd_d1_X;  wire [2:0] ebi_rxd_d1_Y;
199
   wire [4:0] ebi_rxd_d2_X;  wire [2:0] ebi_rxd_d2_Y;
200
   wire [4:0] ebi_rxd_d3_X;  wire [2:0] ebi_rxd_d3_Y;
201
 
202
   assign {ebi_rxd_d1_Y, ebi_rxd_d1_X} = ebi_rxd_d1;
203
   assign {ebi_rxd_d2_Y, ebi_rxd_d2_X} = ebi_rxd_d2;
204
   assign {ebi_rxd_d3_Y, ebi_rxd_d3_X} = ebi_rxd_d3;
205
`endif
206
 
207
   //////////////////////////////////////////////////////////////////////////////
208
   // Decode EARLY_END EPD code sequence
209
   //////////////////////////////////////////////////////////////////////////////   
210
 
211
   wire       early_end_idle;
212
 
213
   // Received code-group sequence K28.5/D/K28.5  
214
   assign     early_end_idle =  (ebi_K_d2  & ebi_rxd_d2 == `K28_5_symbol) &
215
                               ~(ebi_K_d1) &
216
                                (ebi_K     & ebi_rxd    == `K28_5_symbol);
217
 
218
   wire       early_end_config;
219
 
220
   // Received code-group sequence K28.5/(D21.5 | D2.2)/D0.0
221
   assign     early_end_config  = (( ebi_K_d2 &  ebi_rxd_d2  == `K28_5_symbol) &
222
                                   (~ebi_K_d1 & (ebi_rxd_d1  == `D21_5_symbol | ebi_rxd_d1 == `D2_2_symbol)) &
223
                                   (~ebi_K    &  ebi_rxd     == `D0_0_symbol));
224
 
225
   // EARLY_END state in 802.3-2008 Clause 36 Figure 36-7b
226
   reg        early_end;
227
 
228
   always @(posedge ck, posedge reset)
229
     if (reset)
230
       early_end <= 0;
231
     else
232
       early_end <= (early_end_idle | early_end_config) & rx_even;
233
 
234
   //////////////////////////////////////////////////////////////////////////////
235
   //  Decode /T/R/K28_5/ EPD code sequence
236
   //////////////////////////////////////////////////////////////////////////////   
237
 
238
   reg        check_end_T_R_K28_5;
239
 
240
   always @(posedge ck, posedge reset)
241
     if (reset)
242
       check_end_T_R_K28_5 <= 0;
243
     else
244
       check_end_T_R_K28_5 <= ((ebi_K_d2 & ebi_rxd_d2  == `K29_7_symbol)  &
245
                               (ebi_K_d1 & ebi_rxd_d1  == `K23_7_symbol)  &
246
                               (ebi_K    & ebi_rxd     == `K28_5_symbol)  & rx_even);
247
 
248
   //////////////////////////////////////////////////////////////////////////////
249
   // Decode /T/R/R/ EPD code sequence
250
   //////////////////////////////////////////////////////////////////////////////  
251
 
252
   reg        check_end_T_R_R;
253
 
254
   always @(posedge ck, posedge reset)
255
     if (reset)
256
       check_end_T_R_R <= 0;
257
     else
258
       check_end_T_R_R <= ((ebi_K_d2 & ebi_rxd_d2  == `K29_7_symbol) &
259
                           (ebi_K_d1 & ebi_rxd_d1  == `K23_7_symbol)  &
260
                           (ebi_K    & ebi_rxd     == `K23_7_symbol));
261
 
262
   //////////////////////////////////////////////////////////////////////////////
263
   // Decode /R/R/R EPD code sequence
264
   //////////////////////////////////////////////////////////////////////////////
265
 
266
   reg        check_end_R_R_R;
267
 
268
   always @(posedge ck, posedge reset)
269
     if (reset)
270
       check_end_R_R_R <= 0;
271
     else
272
       check_end_R_R_R <= ((ebi_K_d2 & ebi_rxd_d2 == `K23_7_symbol) &
273
                           (ebi_K_d1 & ebi_rxd_d1 == `K23_7_symbol) &
274
                           (ebi_K    & ebi_rxd    == `K23_7_symbol));
275
 
276
   //////////////////////////////////////////////////////////////////////////////
277
   // Decode /R/R/28_5 EPD code sequence
278
   //////////////////////////////////////////////////////////////////////////////
279
 
280
   reg        check_end_R_R_K28_5;
281
 
282
   always @(posedge ck, posedge reset)
283
     if (reset)
284
       check_end_R_R_K28_5 <= 0;
285
     else
286
       check_end_R_R_K28_5 <= ((ebi_K_d2 & ebi_rxd_d2 == `K23_7_symbol) &
287
                               (ebi_K_d1 & ebi_rxd_d1 == `K23_7_symbol) &
288
                               (ebi_K    & ebi_rxd    == `K28_5_symbol) & rx_even);
289
 
290
   //////////////////////////////////////////////////////////////////////////////
291
   // Decode /R/R/S EPD code sequence
292
   ////////////////////////////////////////////////////////////////////////////// 
293
 
294
   reg   check_end_R_R_S;
295
 
296
   always @(posedge ck, posedge reset)
297
     if (reset)
298
       check_end_R_R_S <= 0;
299
     else
300
       check_end_R_R_S <= ((ebi_K_d2 & ebi_rxd_d2 == `K23_7_symbol) &
301
                           (ebi_K_d1 & ebi_rxd_d1 == `K23_7_symbol) &
302
                           (ebi_K & ebi_rxd == `K27_7_symbol));
303
 
304
   //////////////////////////////////////////////////////////////////////////////
305
   //  Dx.y and Kx.y symbol decoding 
306
   ////////////////////////////////////////////////////////////////////////////// 
307
 
308
   reg   K28_5_match, D2_2_match, D21_5_match, D5_6_match, D16_2_match;
309
 
310
   always @(posedge ck, posedge reset)
311
     if (reset)
312
       begin
313
          K28_5_match <= 0;
314
          D2_2_match  <= 0;
315
          D21_5_match <= 0;
316
          D5_6_match  <= 0;
317
          D16_2_match <= 0;
318
       end
319
     else begin
320
        K28_5_match <= (ebi_K_d2 &  ebi_rxd_d2 == `K28_5_symbol);
321
        D2_2_match  <= ~ebi_K_d2 & (ebi_rxd_d2 == `D2_2_symbol);
322
        D21_5_match <= ~ebi_K_d2 & (ebi_rxd_d2 == `D21_5_symbol);
323
        D5_6_match  <= ~ebi_K_d2 & (ebi_rxd_d2 == `D5_6_symbol);
324
        D16_2_match <= ~ebi_K_d2 & (ebi_rxd_d2 == `D16_2_symbol);
325
     end
326
 
327
   //////////////////////////////////////////////////////////////////////////////
328
   // Start of packet (/S/), End of Packet (/T/) and Carrier Extend 
329
   // (/R/) symbol matching
330
   //////////////////////////////////////////////////////////////////////////////    
331
 
332
   reg     CE_match, SPD_match, EPD_match;
333
 
334
   always @(posedge ck, posedge reset)
335
     if (reset)
336
       begin
337
         CE_match   <= 0;
338
         SPD_match  <= 0;
339
         EPD_match  <= 0;
340
       end
341
     else
342
       begin
343
         CE_match   <= ebi_K_d2 & (ebi_rxd_d2 == `K23_7_symbol);
344
         SPD_match  <= ebi_K_d2 & (ebi_rxd_d2 == `K27_7_symbol);
345
         EPD_match  <= ebi_K_d2 & (ebi_rxd_d2 == `K29_7_symbol);
346
       end
347
 
348
   //////////////////////////////////////////////////////////////////////////////
349
   //
350
   ////////////////////////////////////////////////////////////////////////////// 
351
 
352
`ifdef MODEL_TECH
353
 
354
   wire [4:0] ebi_rxd_X;  wire [2:0] ebi_rxd_Y;
355
 
356
   assign     ebi_rxd_X = ebi_rxd[4:0];
357
   assign     ebi_rxd_Y = ebi_rxd[7:5];
358
`endif
359
 
360
   //////////////////////////////////////////////////////////////////////////////
361
   // rx_Config_reg
362
   //////////////////////////////////////////////////////////////////////////////  
363
 
364
   reg [15:0] rx_config_d1; reg [15:0] rx_config_d2;  reg [7:0] rx_config_lo;
365
 
366
   reg        rx_config_lo_read, rx_config_hi_read;
367
 
368
   wire [15:0] rx_config_tmp = { ebi_rxd_d3, rx_config_lo };
369
 
370
   always @(posedge ck, posedge reset)
371
     if (reset)
372
       begin
373
          rx_config <= 0; rx_config_set <= 0; rx_config_lo <= 0; rx_config_d1 <= 0; rx_config_d2 <= 0;
374
       end
375
     else
376
       begin
377
          if (rx_config_lo_read)
378
            begin
379
               rx_config_d2  <= rx_config_d1;
380
               rx_config_d1  <= rx_config;
381
               rx_config_lo  <= ebi_rxd_d3;
382
            end
383
          else if (rx_config_hi_read) begin
384
 
385
             rx_config  <= rx_config_tmp;
386
 
387
             rx_config_set <= |rx_config_tmp;
388
          end
389
       end
390
 
391
   //////////////////////////////////////////////////////////////////////////////
392
   // rx_config_cnt
393
   ////////////////////////////////////////////////////////////////////////////// 
394
 
395
   reg [2:0] rx_config_cnt;
396
   reg       rx_config_cnt_m_inc, rx_config_cnt_m_rst;
397
 
398
   always @(posedge ck, posedge reset)
399
     if (reset)
400
       rx_config_cnt <= 0;
401
     else
402
       begin
403
          if      (rx_config_cnt_m_inc) rx_config_cnt <= rx_config_cnt + 1;
404
          else if (rx_config_cnt_m_rst) rx_config_cnt <= 0;
405
       end
406
 
407
   wire rx_config_cnt_done;
408
 
409
   assign rx_config_cnt_done = (rx_config_cnt == 3);
410
 
411
   //////////////////////////////////////////////////////////////////////////////
412
   // receive ability matching
413
   //////////////////////////////////////////////////////////////////////////////    
414
 
415
   wire [6:0] ability; wire [6:0] ability_d1; wire [6:0] ability_d2;
416
 
417
   assign      ability    = { rx_config[15],    rx_config[13:12],    rx_config[8:5]   };
418
   assign      ability_d1 = { rx_config_d1[15], rx_config_d1[13:12], rx_config_d1[8:5]};
419
   assign      ability_d2 = { rx_config_d2[15], rx_config_d2[13:12], rx_config_d2[8:5]};
420
 
421
   assign ability_matched1 = ~| (ability ^ ability_d1);
422
   assign ability_matched2 = ~| (ability ^ ability_d2);
423
 
424
   assign ability_matched = rx_config_cnt_done & ability_matched1 & ability_matched2;
425
 
426
     reg [6:0] ability_matched_reg;
427
 
428
   always @(posedge ck, posedge reset)
429
     if (reset)
430
       ability_matched_reg <= 0;
431
     else begin
432
 
433
        ability_match <= ability_matched;
434
 
435
        if (ability_matched) ability_matched_reg <= ability;
436
     end
437
 
438
   //////////////////////////////////////////////////////////////////////////////
439
   // receive config matching
440
   //////////////////////////////////////////////////////////////////////////////   
441
 
442
   assign rx_config_match1 = ability_matched1 & ~(rx_config[14] ^ rx_config_d1[14]);
443
   assign rx_config_match2 = ability_matched2 & ~(rx_config[14] ^ rx_config_d2[14]);
444
 
445
   assign  rx_config_match = rx_config_match1 & rx_config_match2;
446
 
447
   //////////////////////////////////////////////////////////////////////////////
448
   // receive acknowledge matching
449
   //////////////////////////////////////////////////////////////////////////////    
450
 
451
   always @(posedge ck, posedge reset)
452
 
453
     acknowledge_match <= (reset) ? 0 : ( rx_config_match & rx_config_d2[14] );
454
 
455
   //////////////////////////////////////////////////////////////////////////////
456
   // receive consistency matching
457
   ////////////////////////////////////////////////////////////////////////////// 
458
 
459
   assign        consistency_match = ability_match & ~|(ability_matched_reg ^ ability);
460
 
461
   //////////////////////////////////////////////////////////////////////////////
462
   // receive idle counter/matching
463
   ////////////////////////////////////////////////////////////////////////////// 
464
 
465
   reg [1:0]   idle_cnt;
466
 
467
   reg         idle_cnt_m_inc, idle_cnt_m_clr;
468
 
469
   always @(posedge ck, posedge reset)
470
 
471
      if (reset)
472
           idle_cnt <= 0;
473
      else
474
        begin
475
           if      (idle_cnt_m_clr) idle_cnt <= 0;
476
           else if (idle_cnt_m_inc) idle_cnt <= idle_cnt + 1;
477
        end
478
 
479
   assign idle_match = (idle_cnt == 3);
480
 
481
   //////////////////////////////////////////////////////////////////////////////
482
   // RX_UNITDATA.indicate - Signal from PCS RX -> PCS AutoNeg process
483
   ////////////////////////////////////////////////////////////////////////////// 
484
 
485
   reg    rudi_INVALID_m_set; reg  rudi_IDLE_m_set; reg rudi_CONF_m_set;
486
 
487
   always @(posedge ck, posedge reset)
488
     if (reset)
489
       rudi <= `RUDI_INVALID;
490
     else
491
       begin
492
          if      (rudi_INVALID_m_set)  rudi <= `RUDI_INVALID;
493
          else if (rudi_IDLE_m_set)     rudi <= `RUDI_IDLE;
494
          else if (rudi_CONF_m_set)     rudi <= `RUDI_CONF;
495
       end
496
 
497
   //////////////////////////////////////////////////////////////////////////////
498
   // GMII output 
499
   ////////////////////////////////////////////////////////////////////////////// 
500
 
501
   reg gmii_rxd_false_carrier_m_set, gmii_rxd_preamble_m_set, gmii_rxd_ext_err_m_set;
502
 
503
   reg gmii_rxd_packet_burst_m_set, gmii_rxd_trr_extend_m_set, gmii_rxd_m_set;
504
 
505
   always @(posedge ck, posedge reset)
506
 
507
     if (reset)
508
       gmii_rxd <= 0;
509
     else
510
       begin
511
          gmii_rxd <= (gmii_rxd_m_set)               ? ebi_rxd_d3  :
512
                      (gmii_rxd_false_carrier_m_set) ? 8'b00001110 :
513
                      (gmii_rxd_preamble_m_set)      ? 8'b01010101 :
514
                      (gmii_rxd_ext_err_m_set)       ? 8'b00011111 :
515
                      (gmii_rxd_trr_extend_m_set)    ? 8'b00001111 :
516
                      (gmii_rxd_packet_burst_m_set)  ? 8'b00001111 : 0;
517
       end
518
 
519
   //////////////////////////////////////////////////////////////////////////////
520
   // Current receive state
521
   ////////////////////////////////////////////////////////////////////////////// 
522
 
523
   reg  receiving_m_set, receiving_m_clr;
524
 
525
   always @(posedge ck, posedge reset)
526
     if (reset)
527
       receiving <= 0;
528
     else
529
       begin
530
          if      (receiving_m_set) receiving <= 1;
531
          else if (receiving_m_clr) receiving <= 0;
532
       end
533
 
534
 
535
`ifdef MODEL_TECH
536
  enum logic [4:0] {
537
`else
538
  localparam
539
`endif
540
                    S_PCS_RX_START            = 0,
541
                    S_PCS_RX_LINK_FAILED      = 1,
542
                    S_PCS_RX_WAIT_K           = 2,
543
                    S_PCS_RX_K                = 3,
544
                    S_PCS_RX_CONFIG_CB        = 4,
545
                    S_PCS_RX_CONFIG_CC        = 5,
546
                    S_PCS_RX_CONFIG_CD        = 6,
547
                    S_PCS_RX_INVALID          = 7,
548
                    S_PCS_RX_IDLE_D           = 8,
549
                    S_PCS_RX_FALSE_CARRIER    = 9,
550
                    S_PCS_RX_START_OF_PACKET  = 10,
551
                    S_PCS_RX_RECEIVE          = 11,
552
                    S_PCS_RX_EARLY_END        = 12,
553
                    S_PCS_RX_TRI_RRI          = 13,
554
                    S_PCS_RX_TRR_EXTEND       = 14,
555
                    S_PCS_RX_EPD2_CHECK_END   = 15,
556
                    S_PCS_RX_PACKET_BURST_RRS = 16,
557
                    S_PCS_RX_EXTEND_ERR       = 17,
558
                    S_PCS_RX_EARLY_END_EXT    = 18,
559
                    S_PCS_RX_DATA_ERROR       = 19,
560
                    S_PCS_RX_DATA             = 20
561
`ifdef MODEL_TECH
562
  } pcs_rx_present, pcs_rx_next;
563
`else
564
   ; reg [4:0] pcs_rx_present, pcs_rx_next;
565
`endif
566
 
567
   //////////////////////////////////////////////////////////////////////////////
568
   // gmii_rx_er ctrl
569
   //////////////////////////////////////////////////////////////////////////////
570
 
571
   reg gmii_rx_er_m_set, gmii_rx_er_m_clr;
572
 
573
   always @(posedge ck, posedge reset)
574
     if (reset)
575
       gmii_rx_er <= 0;
576
     else
577
       begin
578
          if      (gmii_rx_er_m_set) gmii_rx_er <= 1;
579
          else if (gmii_rx_er_m_clr) gmii_rx_er <= 0;
580
       end
581
 
582
   //////////////////////////////////////////////////////////////////////////////
583
   // gmii_rx_dv ctrl
584
   ////////////////////////////////////////////////////////////////////////////// 
585
 
586
   reg gmii_rx_dv_m_set, gmii_rx_dv_m_clr;
587
 
588
   always @(posedge ck, posedge reset)
589
     if (reset)
590
       gmii_rx_dv <= 0;
591
     else
592
       begin
593
          if      (gmii_rx_dv_m_set) gmii_rx_dv <= 1;
594
          else if (gmii_rx_dv_m_clr) gmii_rx_dv <= 0;
595
       end
596
 
597
   //////////////////////////////////////////////////////////////////////////////
598
   // 
599
   ////////////////////////////////////////////////////////////////////////////// 
600
 
601
   wire  xmit_DATA, xmit_nDATA, xmit_DATA_CD, xmit_DATA_nCD;
602
 
603
   assign xmit_DATA = (xmit == `XMIT_DATA);
604
 
605
   assign xmit_nDATA = (xmit != `XMIT_DATA);
606
 
607
   assign xmit_DATA_CD = (xmit_DATA & carrier_detect_d3);
608
 
609
   assign xmit_DATA_nCD = (xmit_DATA & ~carrier_detect_d3);
610
 
611
   wire   xmit_DATA_CD_SPD, xmit_DATA_CD_nSPD, xmit_DATA_CD_nSPD_nK28_5;
612
 
613
   assign xmit_DATA_CD_SPD = xmit_DATA_CD & SPD_match;
614
 
615
   assign xmit_DATA_CD_nSPD = xmit_DATA_CD & ~SPD_match;
616
 
617
   assign xmit_DATA_CD_nSPD_nK28_5 = xmit_DATA_CD_nSPD & ~K28_5_match;
618
 
619
 
620
   //////////////////////////////////////////////////////////////////////////////
621
   // receive state machine registered part.
622
   //////////////////////////////////////////////////////////////////////////////    
623
 
624
   always @(posedge ck, posedge reset)
625
 
626
     pcs_rx_present <= (reset) ? S_PCS_RX_START :  pcs_rx_next;
627
 
628
   //////////////////////////////////////////////////////////////////////////////
629
   // receive state machine - IEEE 802.3-2008 Clause 36  Figure 36-7a, 36-7b
630
   ////////////////////////////////////////////////////////////////////////////// 
631
 
632
   always @*
633
     begin
634
        pcs_rx_next = pcs_rx_present;
635
 
636
        rx_config_lo_read = 0; rx_config_hi_read = 0;
637
 
638
        receiving_m_set = 0; receiving_m_clr = 0;
639
 
640
        gmii_rxd_false_carrier_m_set = 0; gmii_rxd_preamble_m_set = 0; gmii_rxd_ext_err_m_set = 0;
641
 
642
        gmii_rxd_packet_burst_m_set = 0; gmii_rxd_trr_extend_m_set = 0; gmii_rxd_m_set = 0;
643
 
644
        idle_cnt_m_clr = 0; idle_cnt_m_inc = 0;
645
 
646
        gmii_rx_er_m_set = 0; gmii_rx_er_m_clr = 0;
647
 
648
        gmii_rx_dv_m_set = 0; gmii_rx_dv_m_clr = 0;
649
 
650
        rudi_INVALID_m_set = 0; rudi_IDLE_m_set = 0; rudi_CONF_m_set = 0;
651
 
652
        rx_config_cnt_m_inc = 0; rx_config_cnt_m_rst = 0;
653
 
654
        ge_x_pcs_rx_stats_inc = 16'h0000;
655
 
656
        case (pcs_rx_present)
657
 
658
          S_PCS_RX_START:
659
            begin
660
               pcs_rx_next = S_PCS_RX_LINK_FAILED;
661
            end
662
 
663
          S_PCS_RX_LINK_FAILED:
664
            begin
665
               rudi_INVALID_m_set = (xmit_nDATA);
666
 
667
               if (receiving) begin receiving_m_clr = 1;  gmii_rx_er_m_set = 1; end
668
               else           begin gmii_rx_dv_m_clr = 1; gmii_rx_er_m_clr = 1; end
669
 
670
               pcs_rx_next = S_PCS_RX_WAIT_K;
671
            end
672
 
673
          S_PCS_RX_WAIT_K:
674
            begin
675
               rx_config_cnt_m_rst = 1;
676
 
677
               receiving_m_clr = 1; gmii_rx_dv_m_clr = 1; gmii_rx_er_m_clr = 1;
678
 
679
               pcs_rx_next = (K28_5_match & rx_even_d3) ? S_PCS_RX_K : S_PCS_RX_WAIT_K;
680
            end
681
 
682
 
683
          S_PCS_RX_K:
684
            begin
685
               receiving_m_clr = 1; gmii_rx_dv_m_clr = 1; gmii_rx_er_m_clr = 1;
686
 
687
               rudi_IDLE_m_set = (xmit_nDATA & ~ebi_K_d3 & ~D21_5_match & ~D2_2_match) |
688
                                 (xmit_DATA & ~D21_5_match & ~D2_2_match);
689
 
690
               pcs_rx_next = (D21_5_match | D2_2_match)                              ? S_PCS_RX_CONFIG_CB   :
691
                             ((xmit_nDATA) & ~ebi_K_d3 & ~D21_5_match & ~D2_2_match) ? S_PCS_RX_IDLE_D      :
692
                             ((xmit_DATA) & ~D21_5_match & ~D2_2_match)              ? S_PCS_RX_IDLE_D      :
693
                             ((xmit_nDATA) & ebi_K_d3)                               ? S_PCS_RX_INVALID     : S_PCS_RX_INVALID;
694
            end
695
 
696
          S_PCS_RX_CONFIG_CB:
697
            begin
698
               // Keep a count of the number of consecutive /C/ streams 
699
               rx_config_cnt_m_inc = ~rx_config_cnt_done;
700
 
701
               rx_config_lo_read = ~ebi_K_d3;
702
 
703
               receiving_m_clr = 1; gmii_rx_dv_m_clr = 1; gmii_rx_er_m_clr = 1;
704
 
705
               pcs_rx_next = (ebi_K_d3) ? S_PCS_RX_INVALID : S_PCS_RX_CONFIG_CC;
706
            end
707
 
708
 
709
          S_PCS_RX_CONFIG_CC:
710
            begin
711
               rx_config_hi_read = ~ebi_K_d3;  idle_cnt_m_clr = 1;
712
 
713
               // Signal from RX -> ANEG indicating /C/ ordered set received
714
               rudi_CONF_m_set = ~ebi_K_d3;
715
 
716
               pcs_rx_next = (ebi_K_d3) ? S_PCS_RX_INVALID : S_PCS_RX_CONFIG_CD;
717
            end
718
 
719
          S_PCS_RX_CONFIG_CD:
720
            begin
721
               pcs_rx_next = (K28_5_match & rx_even_d3) ? S_PCS_RX_K : S_PCS_RX_INVALID;
722
            end
723
 
724
 
725
          S_PCS_RX_INVALID:
726
            begin
727
               // Signal from RX -> ANEG indicating INVALID
728
               rudi_INVALID_m_set = (xmit == `XMIT_CONFIGURATION);
729
 
730
               receiving_m_set = (xmit_DATA);
731
 
732
               pcs_rx_next = (K28_5_match & rx_even_d3)  ? S_PCS_RX_K       :
733
                             (~K28_5_match & rx_even_d3) ? S_PCS_RX_WAIT_K  : S_PCS_RX_INVALID;
734
            end
735
 
736
 
737
          S_PCS_RX_IDLE_D:
738
            begin
739
               // Must be receiving a IDLE so reset config cnt and idle_matcher logic
740
               rx_config_cnt_m_rst = 1;  idle_cnt_m_inc = ~idle_match;
741
 
742
               // Signal from RX -> ANEG indicating /I/ ordered set received
743
               rudi_IDLE_m_set = 1;
744
 
745
               // Generate rx_dv only if we've detected a START_OF_PACKET
746
               if (xmit_DATA_CD_SPD)         gmii_rx_dv_m_set = 1; else gmii_rx_dv_m_clr = 1;
747
 
748
               // Generate rx_er if we've detected a FALSE_CARRIER
749
               if (xmit_DATA_CD_nSPD_nK28_5) gmii_rx_er_m_set = 1; else gmii_rx_er_m_clr = 1;
750
 
751
               if (xmit_DATA_CD)
752
                 begin
753
                    if (~K28_5_match)
754
                      begin
755
                         receiving_m_set = 1;
756
                         if (SPD_match) gmii_rxd_preamble_m_set = 1; else gmii_rxd_false_carrier_m_set = 1;
757
                      end
758
                 end
759
               else receiving_m_clr = 1;
760
 
761
               pcs_rx_next = (~K28_5_match & ~xmit_DATA    )  ? S_PCS_RX_INVALID       :
762
                             ( xmit_DATA_CD_SPD            )  ? S_PCS_RX_RECEIVE       :
763
                             ( xmit_DATA_nCD | K28_5_match )  ? S_PCS_RX_K             :
764
                             ( xmit_DATA_CD_nSPD           )  ? S_PCS_RX_FALSE_CARRIER :  S_PCS_RX_IDLE_D;
765
 
766
               ge_x_pcs_rx_stats_inc[0] = xmit_DATA_CD_SPD;
767
 
768
            end
769
 
770
 
771
          S_PCS_RX_FALSE_CARRIER:
772
            begin
773
               gmii_rx_er_m_set = 1; gmii_rxd_false_carrier_m_set = 1;
774
 
775
               pcs_rx_next = (K28_5_match & rx_even_d3) ? S_PCS_RX_K : S_PCS_RX_FALSE_CARRIER;
776
            end
777
 
778
          //----------------------------------------------------------------------------
779
          // IEEE 802.3-2008 Clause 36  Figure 36-7b
780
 
781
          S_PCS_RX_START_OF_PACKET:
782
            begin
783
               gmii_rx_dv_m_set = 1; gmii_rx_er_m_clr = 1; gmii_rxd_preamble_m_set = 1;
784
 
785
               pcs_rx_next = S_PCS_RX_RECEIVE;
786
            end
787
 
788
          S_PCS_RX_RECEIVE:
789
            begin
790
 
791
               if (early_end)  // EARLY_END
792
                 begin
793
                    ge_x_pcs_rx_stats_inc[2] = 1;
794
 
795
                    gmii_rx_er_m_set = 1; pcs_rx_next = S_PCS_RX_EARLY_END;
796
                 end
797
 
798
               else if (check_end_T_R_K28_5) // TRI+RRI
799
                 begin
800
 
801
                    ge_x_pcs_rx_stats_inc[3] = 1;
802
 
803
                    receiving_m_clr = 1; gmii_rx_dv_m_clr  = 1;  gmii_rx_er_m_clr = 1;
804
 
805
                    pcs_rx_next = S_PCS_RX_TRI_RRI;
806
                 end
807
 
808
               else if (check_end_T_R_R) // TRR+EXTEND
809
                 begin
810
 
811
                    ge_x_pcs_rx_stats_inc[5] = 1;
812
 
813
                    gmii_rx_dv_m_clr  = 1;  gmii_rx_er_m_set = 1; gmii_rxd_trr_extend_m_set = 1;
814
 
815
                    pcs_rx_next = S_PCS_RX_EPD2_CHECK_END;
816
                 end
817
 
818
               else if (check_end_R_R_R) // EARLY_END_EXT
819
                 begin
820
 
821
                    ge_x_pcs_rx_stats_inc[6] = 1;
822
 
823
                    gmii_rx_er_m_set = 1;  pcs_rx_next = S_PCS_RX_EPD2_CHECK_END;
824
                 end
825
 
826
               else if (~ebi_K_d3) // RX_DATA
827
                 begin
828
                    ge_x_pcs_rx_stats_inc[1] = 1;
829
 
830
                    gmii_rx_er_m_clr = 1; gmii_rxd_m_set = 1;
831
                 end
832
 
833
               else  // RX_DATA_ERROR
834
                 gmii_rx_er_m_set = 1;
835
            end
836
 
837
 
838
          S_PCS_RX_EARLY_END:
839
            begin
840
               pcs_rx_next =  (D21_5_match | D2_2_match) ? S_PCS_RX_CONFIG_CB : S_PCS_RX_IDLE_D;
841
            end
842
 
843
          S_PCS_RX_TRI_RRI:
844
            begin
845
               pcs_rx_next = (K28_5_match) ? S_PCS_RX_K : S_PCS_RX_TRI_RRI;
846
            end
847
 
848
          S_PCS_RX_TRR_EXTEND:
849
            begin
850
               gmii_rx_dv_m_clr = 1; gmii_rx_er_m_set = 1; gmii_rxd_trr_extend_m_set = 1;
851
 
852
               pcs_rx_next = S_PCS_RX_EPD2_CHECK_END;
853
            end
854
 
855
 
856
          S_PCS_RX_EPD2_CHECK_END:
857
            begin
858
 
859
               if (check_end_R_R_R)
860
                 begin
861
 
862
                    gmii_rx_dv_m_clr  = 1;  gmii_rx_er_m_set = 1; gmii_rxd_trr_extend_m_set = 1;
863
                 end
864
 
865
               else if (check_end_R_R_K28_5)
866
                 begin
867
 
868
                    ge_x_pcs_rx_stats_inc[4] = 1;
869
 
870
                    receiving_m_clr = 1; gmii_rx_dv_m_clr = 1; gmii_rx_er_m_clr = 1;
871
 
872
                 end
873
 
874
               else if (check_end_R_R_S)
875
                 begin
876
                    ge_x_pcs_rx_stats_inc[7] = 1;
877
                 end
878
 
879
               pcs_rx_next = (check_end_R_R_R)     ? S_PCS_RX_TRR_EXTEND       :
880
                             (check_end_R_R_K28_5) ? S_PCS_RX_TRI_RRI          :
881
                             (check_end_R_R_S)     ? S_PCS_RX_PACKET_BURST_RRS : S_PCS_RX_EXTEND_ERR;
882
            end
883
 
884
          S_PCS_RX_PACKET_BURST_RRS:
885
            begin
886
               gmii_rx_dv_m_clr = 1; gmii_rxd_packet_burst_m_set = 1;
887
 
888
               pcs_rx_next = (SPD_match) ? S_PCS_RX_START_OF_PACKET : S_PCS_RX_PACKET_BURST_RRS;
889
            end
890
 
891
           S_PCS_RX_EXTEND_ERR:
892
             begin
893
                gmii_rx_dv_m_clr  = 1;  gmii_rxd_ext_err_m_set = 1;
894
 
895
                pcs_rx_next = (SPD_match)                              ? S_PCS_RX_START_OF_PACKET :
896
                              (K28_5_match & rx_even_d3)               ? S_PCS_RX_K           :
897
                              (~SPD_match & ~K28_5_match & rx_even_d3) ? S_PCS_RX_EPD2_CHECK_END  : S_PCS_RX_EXTEND_ERR;
898
             end
899
 
900
          S_PCS_RX_EARLY_END_EXT:
901
            begin
902
               gmii_rx_er_m_set = 1;
903
 
904
               pcs_rx_next = S_PCS_RX_EPD2_CHECK_END;
905
            end
906
 
907
          S_PCS_RX_DATA_ERROR:
908
            begin
909
               gmii_rx_er_m_set = 1;
910
 
911
               pcs_rx_next = S_PCS_RX_RECEIVE;
912
            end
913
 
914
          S_PCS_RX_DATA:
915
            begin
916
               gmii_rx_er_m_clr = 1; gmii_rxd_m_set = 1;
917
 
918
               pcs_rx_next = S_PCS_RX_RECEIVE;
919
            end
920
        endcase
921
 
922
        if      (~signal_detect)  pcs_rx_next = S_PCS_RX_LINK_FAILED;
923
        else if (~sync_status_d3) pcs_rx_next = S_PCS_RX_LINK_FAILED;
924
        else if (soft_reset)      pcs_rx_next = S_PCS_RX_WAIT_K;
925
 
926
     end
927
 
928
endmodule

powered by: WebSVN 2.1.0

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