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

Subversion Repositories 1000base-x

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 dwp
 
2
//////////////////////////////////////////////////////////////////////
3
////                                                              ////
4
////  File name "ge_1000baseX_sync.v"                             ////
5
////                                                              ////
6
////  This file is part of the :                                  ////
7
////                                                              ////
8
//// "1000BASE-X IEEE 802.3-2008 Clause 36 - PCS project"         ////
9
////                                                              ////
10
////  http://opencores.org/project,1000base-x                     ////
11
////                                                              ////
12
////  Author(s):                                                  ////
13
////      - D.W.Pegler Cambridge Broadband Networks Ltd           ////
14
////                                                              ////
15
////      { peglerd@gmail.com, dwp@cambridgebroadand.com }        ////
16
////                                                              ////
17
//////////////////////////////////////////////////////////////////////
18
////                                                              ////
19
//// Copyright (C) 2009 AUTHORS. All rights reserved.             ////
20
////                                                              ////
21
//// This source file may be used and distributed without         ////
22
//// restriction provided that this copyright statement is not    ////
23
//// removed from the file and that any derivative work contains  ////
24
//// the original copyright notice and the associated disclaimer. ////
25
////                                                              ////
26
//// This source file is free software; you can redistribute it   ////
27
//// and/or modify it under the terms of the GNU Lesser General   ////
28
//// Public License as published by the Free Software Foundation; ////
29
//// either version 2.1 of the License, or (at your option) any   ////
30
//// later version.                                               ////
31
////                                                              ////
32
//// This source is distributed in the hope that it will be       ////
33
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
34
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
35
//// PURPOSE.  See the GNU Lesser General Public License for more ////
36
//// details.                                                     ////
37
////                                                              ////
38
//// You should have received a copy of the GNU Lesser General    ////
39
//// Public License along with this source; if not, download it   ////
40
//// from http://www.opencores.org/lgpl.shtml                     ////
41
////                                                              ////
42
//////////////////////////////////////////////////////////////////////
43
////                                                              ////
44
//// This module is based on the coding method described in       ////
45
//// IEEE Std 802.3-2008 Clause 36 "Physical Coding Sublayer(PCS) ////
46
//// and Physical Medium Attachment (PMA) sublayer, type          ////
47
//// 1000BASE-X"; see :                                           ////
48
////                                                              ////
49
//// http://standards.ieee.org/about/get/802/802.3.html           ////
50
//// and                                                          ////
51
//// doc/802.3-2008_section3.pdf, Clause/Section 36.              ////
52
////                                                              ////
53
//////////////////////////////////////////////////////////////////////
54
 
55
`include "ge_1000baseX_constants.v"
56
 
57
`include "timescale.v"
58
 
59
module ge_1000baseX_sync(
60
 
61
   //  clocks and reset 
62
   input               ck,
63
   input               reset,
64
 
65
   //  Startup interface. 
66
   input               startup_enable,
67
 
68
   //  Signal detect from FO transceiver             
69
   input               signal_detect,
70
 
71
   //  Receive EBI bus from 8b10 decode 
72
   input [7:0]          ebi_rxd,
73
   input               ebi_K,
74
 
75
   output reg [7:0]    ebi_rxd_out,
76
   output reg          ebi_K_out,
77
 
78
   //  8B/10B disparity and coding errors 
79
   input               decoder_disparity_err,
80
   input               decoder_coding_err,
81
 
82
   //  RX sync status 
83
   output reg          sync_status,
84
 
85
   output reg          rx_even,
86
 
87
   input               loopback
88
   );
89
 
90
   //////////////////////////////////////////////////////////////////////////////
91
   //  Running Disparity
92
   //////////////////////////////////////////////////////////////////////////////  
93
 
94
   reg                 running_disparity;
95
   reg                 running_disparity_positive_m_set;
96
   reg                 running_disparity_negative_m_set;
97
 
98
   always @(posedge ck, posedge reset)
99
 
100
     // Assume negative (0) disparity at startup
101
     if (reset) running_disparity <= 0;
102
 
103
     else
104
       begin
105
          if      (running_disparity_positive_m_set) running_disparity <= 1;
106
          else if (running_disparity_negative_m_set) running_disparity <= 0;
107
       end
108
 
109
   //////////////////////////////////////////////////////////////////////////////
110
   // sync_status ctrl
111
   //////////////////////////////////////////////////////////////////////////////
112
 
113
   reg                 sync_m_acquired, sync_m_lost;
114
 
115
   always @(posedge ck, posedge reset)
116
     if (reset)
117
       sync_status <= 0;
118
     else
119
       begin
120
          if      (sync_m_acquired) begin sync_status <= 1; end
121
          else if (sync_m_lost)     begin sync_status <= 0; end
122
       end
123
 
124
   //////////////////////////////////////////////////////////////////////////////
125
   // rx_even reg
126
   //////////////////////////////////////////////////////////////////////////////   
127
 
128
   reg    rx_even_m_init, rx_even_m_set, rx_even_m_clr, rx_even_m_toggle;
129
 
130
   always @(posedge ck, posedge reset)
131
     if (reset)
132
       rx_even <= 1;
133
     else
134
        begin
135
           if      (rx_even_m_init)   rx_even <= 1;
136
           else if (rx_even_m_set)    rx_even <= 1;
137
           else if (rx_even_m_clr)    rx_even <= 0;
138
           else if (rx_even_m_toggle) rx_even <= ~rx_even;
139
        end
140
 
141
   //////////////////////////////////////////////////////////////////////////////
142
   //  COMMAs can be K28.1, K28.5 or K28.7 - see table 36-2 pg 45
143
   //////////////////////////////////////////////////////////////////////////////   
144
 
145
   reg [7:0]    ebi_rxd_d1;  reg          ebi_K_d1;
146
 
147
   always @(posedge ck, posedge reset)
148
     if (reset)
149
       begin ebi_rxd_d1 <= 0; ebi_K_d1 <= 0; end
150
     else
151
       begin ebi_rxd_d1 <= ebi_rxd; ebi_K_d1 <= ebi_K; end
152
 
153
 
154
   always @(posedge ck, posedge reset)
155
     if (reset)
156
       begin ebi_rxd_out <= 0; ebi_K_out <=0; end
157
     else
158
       begin ebi_rxd_out <= ebi_rxd_d1; ebi_K_out <= ebi_K_d1; end
159
 
160
   //////////////////////////////////////////////////////////////////////////////
161
   //
162
   //////////////////////////////////////////////////////////////////////////////   
163
 
164
   assign   K28_1_RX  = (ebi_rxd_d1 == `K28_1_symbol);
165
   assign   K28_5_RX  = (ebi_rxd_d1 == `K28_5_symbol);
166
   assign   K28_7_RX  = (ebi_rxd_d1 == `K28_7_symbol);
167
 
168
   assign   COMMA_RX = K28_1_RX | K28_5_RX | K28_7_RX;
169
 
170
   assign   COMMA_match  = COMMA_RX & ebi_K_d1;
171
 
172
`ifdef MODEL_TECH
173
   wire [4:0] ebi_rxd_X;  wire [2:0] ebi_rxd_Y;
174
 
175
   assign     ebi_rxd_X = ebi_rxd[4:0];
176
   assign     ebi_rxd_Y = ebi_rxd[7:5];
177
`endif
178
 
179
   //////////////////////////////////////////////////////////////////////////////
180
   //  Definition of /INVLAID/ as per section 36.2.4.6
181
   //////////////////////////////////////////////////////////////////////////////   
182
   reg        INVALID;
183
 
184
   always @(posedge ck, posedge reset)
185
 
186
     INVALID <= (reset) ? 0 : decoder_disparity_err | decoder_coding_err;
187
 
188
   assign VALID = ~INVALID;
189
 
190
   //////////////////////////////////////////////////////////////////////////////
191
   //  good_cgs ctrl
192
   //////////////////////////////////////////////////////////////////////////////   
193
 
194
   reg [2:0]            good_cgs;
195
   reg                 good_cgs_m_init, good_cgs_m_inc, good_cgs_m_cnt;
196
 
197
   always @(posedge ck, posedge reset)
198
     if (reset)
199
       good_cgs <= 0;
200
     else
201
       begin
202
          if      (good_cgs_m_init)  good_cgs <= 0;
203
          else if (good_cgs_m_cnt)   good_cgs <= 1;
204
          else if (good_cgs_m_inc)   good_cgs <= good_cgs + 1 ;
205
 
206
       end
207
 
208
   assign good_cgs_done = (good_cgs == 3);
209
 
210
   assign cgbad = INVALID | (COMMA_match & rx_even);
211
 
212
   assign cggood = ~cgbad;
213
 
214
   //////////////////////////////////////////////////////////////////////////////
215
   //
216
   //////////////////////////////////////////////////////////////////////////////
217
 
218
`ifdef MODEL_TECH
219
  enum logic [3:0] {
220
`else
221
  localparam
222
`endif
223
                    S_PCS_SYNC_RUN            = 0,
224
                    S_PCS_SYNC_LOSS_OF_SYNC   = 1,
225
                    S_PCS_SYNC_COMMA_DETECT_1 = 2,
226
                    S_PCS_SYNC_ACQUIRE_SYNC_1 = 3,
227
                    S_PCS_SYNC_COMMA_DETECT_2 = 4,
228
                    S_PCS_SYNC_ACQUIRE_SYNC_2 = 5,
229
                    S_PCS_SYNC_COMMA_DETECT_3 = 6,
230
                    S_PCS_SYNC_ACQUIRED_1     = 7,
231
                    S_PCS_SYNC_ACQUIRED_2     = 8,
232
                    S_PCS_SYNC_ACQUIRED_3     = 9,
233
                    S_PCS_SYNC_ACQUIRED_4     = 10,
234
                    S_PCS_SYNC_ACQUIRED_2A    = 11,
235
                    S_PCS_SYNC_ACQUIRED_3A    = 12,
236
                    S_PCS_SYNC_ACQUIRED_4A    = 13
237
`ifdef MODEL_TECH
238
  } pcs_sync_present, pcs_sync_next;
239
`else
240
   ; reg [3:0] pcs_sync_present, pcs_sync_next;
241
`endif
242
 
243
   //////////////////////////////////////////////////////////////////////////////
244
   // sync state machine registered part.
245
   //////////////////////////////////////////////////////////////////////////////   
246
 
247
   always @(posedge ck or posedge reset)
248
 
249
     pcs_sync_present <= (reset) ? S_PCS_SYNC_RUN : pcs_sync_next;
250
 
251
   //////////////////////////////////////////////////////////////////////////////
252
   //  sync state machine  - IEEE 802.3-2008 Clause 36  Figure 36-9
253
   //////////////////////////////////////////////////////////////////////////////      
254
 
255
   always @*
256
     begin
257
        pcs_sync_next = pcs_sync_present;
258
 
259
        good_cgs_m_init = 0; good_cgs_m_inc = 0; good_cgs_m_cnt = 0;
260
 
261
        sync_m_acquired = 0; sync_m_lost = 0;
262
 
263
        rx_even_m_init = 0; rx_even_m_set = 0; rx_even_m_clr = 0; rx_even_m_toggle = 0;
264
 
265
        running_disparity_negative_m_set = 0; running_disparity_positive_m_set = 0;
266
 
267
        case (pcs_sync_present)
268
 
269
          S_PCS_SYNC_RUN:
270
            begin
271
               if (startup_enable) pcs_sync_next = S_PCS_SYNC_LOSS_OF_SYNC;
272
            end
273
 
274
          S_PCS_SYNC_LOSS_OF_SYNC :
275
            begin
276
 
277
               sync_m_lost = sync_status;
278
 
279
               if ((signal_detect | loopback) & COMMA_match)
280
                 begin
281
                    rx_even_m_set = 1; pcs_sync_next = S_PCS_SYNC_COMMA_DETECT_1;
282
                 end
283
               else
284
                 rx_even_m_toggle = 1;
285
            end
286
 
287
          S_PCS_SYNC_COMMA_DETECT_1 :
288
            begin
289
               rx_even_m_toggle = 1;
290
 
291
               pcs_sync_next = (~ebi_K_d1 & ~cgbad) ? S_PCS_SYNC_ACQUIRE_SYNC_1 : S_PCS_SYNC_LOSS_OF_SYNC;
292
            end
293
 
294
          S_PCS_SYNC_ACQUIRE_SYNC_1:
295
            begin
296
               if (~rx_even & COMMA_match)
297
                 begin
298
                    rx_even_m_set = 1; pcs_sync_next = S_PCS_SYNC_COMMA_DETECT_2;
299
                 end
300
               else
301
                 begin
302
                    rx_even_m_toggle = 1;
303
 
304
                    pcs_sync_next = (~COMMA_match & ~INVALID) ? S_PCS_SYNC_ACQUIRE_SYNC_1 : S_PCS_SYNC_LOSS_OF_SYNC;
305
                 end
306
            end
307
 
308
          S_PCS_SYNC_COMMA_DETECT_2:
309
            begin
310
               rx_even_m_toggle = 1;
311
 
312
               pcs_sync_next = (~ebi_K_d1 & ~cgbad) ? S_PCS_SYNC_ACQUIRE_SYNC_2 : S_PCS_SYNC_LOSS_OF_SYNC;
313
            end
314
 
315
          S_PCS_SYNC_ACQUIRE_SYNC_2:
316
            begin
317
               if (~rx_even & COMMA_match)
318
                 begin
319
                    rx_even_m_set = 1; pcs_sync_next = S_PCS_SYNC_COMMA_DETECT_3;
320
                 end
321
               else
322
                 begin
323
                    rx_even_m_toggle = 1;
324
 
325
                    pcs_sync_next = (~COMMA_match & ~INVALID) ? S_PCS_SYNC_ACQUIRE_SYNC_2 : S_PCS_SYNC_LOSS_OF_SYNC;
326
                 end
327
            end
328
 
329
          S_PCS_SYNC_COMMA_DETECT_3:
330
            begin
331
               rx_even_m_toggle = 1;
332
 
333
               pcs_sync_next = (~ebi_K_d1 & ~cgbad) ? S_PCS_SYNC_ACQUIRED_1 : S_PCS_SYNC_LOSS_OF_SYNC;
334
 
335
               sync_m_acquired = ~ebi_K_d1;
336
            end
337
 
338
          S_PCS_SYNC_ACQUIRED_1:
339
            begin
340
               rx_even_m_toggle = 1;
341
 
342
               pcs_sync_next = cggood ? S_PCS_SYNC_ACQUIRED_1 : S_PCS_SYNC_ACQUIRED_2;
343
            end
344
 
345
          S_PCS_SYNC_ACQUIRED_2:
346
            begin
347
               rx_even_m_toggle = 1;
348
 
349
               if (cggood) good_cgs_m_cnt = 1; else good_cgs_m_init = 1;
350
 
351
               pcs_sync_next = cggood ? S_PCS_SYNC_ACQUIRED_2A : S_PCS_SYNC_ACQUIRED_3;
352
            end
353
 
354
          S_PCS_SYNC_ACQUIRED_3:
355
            begin
356
 
357
               rx_even_m_toggle = 1;
358
 
359
               if (cggood) good_cgs_m_cnt = 1; else good_cgs_m_init = 1;
360
 
361
               pcs_sync_next = cggood ? S_PCS_SYNC_ACQUIRED_3A: S_PCS_SYNC_ACQUIRED_4;
362
            end
363
 
364
          S_PCS_SYNC_ACQUIRED_4:
365
            begin
366
 
367
               rx_even_m_toggle = 1;
368
 
369
               if (cggood) good_cgs_m_cnt = 1; else good_cgs_m_init = 1;
370
 
371
               pcs_sync_next = cggood ? S_PCS_SYNC_ACQUIRED_4A: S_PCS_SYNC_LOSS_OF_SYNC;
372
            end
373
 
374
          S_PCS_SYNC_ACQUIRED_2A:
375
            begin
376
               rx_even_m_toggle = 1; good_cgs_m_inc = 1;
377
 
378
               pcs_sync_next = (cgbad)         ? S_PCS_SYNC_ACQUIRED_3 :
379
                               (good_cgs_done) ? S_PCS_SYNC_ACQUIRED_1 : S_PCS_SYNC_ACQUIRED_2A;
380
            end
381
 
382
          S_PCS_SYNC_ACQUIRED_3A:
383
            begin
384
               rx_even_m_toggle = 1; good_cgs_m_inc = 1;
385
 
386
                pcs_sync_next = (cgbad)         ? S_PCS_SYNC_ACQUIRED_4 :
387
                                (good_cgs_done) ? S_PCS_SYNC_ACQUIRED_2 : S_PCS_SYNC_ACQUIRED_3A;
388
            end
389
 
390
          S_PCS_SYNC_ACQUIRED_4A:
391
            begin
392
               rx_even_m_toggle = 1; good_cgs_m_inc = 1;
393
 
394
               pcs_sync_next = (cgbad)         ? S_PCS_SYNC_LOSS_OF_SYNC :
395
                               (good_cgs_done) ? S_PCS_SYNC_ACQUIRED_3   : S_PCS_SYNC_ACQUIRED_4A;
396
            end
397
 
398
        endcase
399
 
400
        if (~signal_detect) pcs_sync_next = S_PCS_SYNC_LOSS_OF_SYNC;
401
     end
402
 
403
endmodule

powered by: WebSVN 2.1.0

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