Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: xpcs_rxio_sync_sm.v | |
4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | // | |
7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | // | |
9 | // This program is free software; you can redistribute it and/or modify | |
10 | // it under the terms of the GNU General Public License as published by | |
11 | // the Free Software Foundation; version 2 of the License. | |
12 | // | |
13 | // This program is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | // | |
18 | // You should have received a copy of the GNU General Public License | |
19 | // along with this program; if not, write to the Free Software | |
20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | // | |
22 | // For the avoidance of doubt, and except that if any non-GPL license | |
23 | // choice is available it will apply instead, Sun elects to use only | |
24 | // the General Public License version 2 (GPLv2) at this time for any | |
25 | // software where a choice of GPL license versions is made | |
26 | // available with the language indicating that GPLv2 or any later version | |
27 | // may be used, or where a choice of which version of the GPL is applied is | |
28 | // otherwise unspecified. | |
29 | // | |
30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | // CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | // have any questions. | |
33 | // | |
34 | // ========== Copyright Header End ============================================ | |
35 | // **************************************************************** | |
36 | // | |
37 | // Sun Proprietary/Confidential: Internal Use Only | |
38 | // | |
39 | // **************************************************************** | |
40 | // Design: XPCS RX IO Interface | |
41 | // Block: XPCS RX Sync state machine | |
42 | // Author: Carlos Castil | |
43 | // | |
44 | // Module: xpcs_rxio_sync_sm | |
45 | // File: xpcs_rxio_sync_sm.v | |
46 | // | |
47 | // Description: This block contains a comma detector compliant | |
48 | // to ieee 802.3ae clause 48 fig 48-7. | |
49 | // | |
50 | // Revision History | |
51 | // ------------------------------------------------------------ | |
52 | // Ver Date Comments | |
53 | // ------------------------------------------------------------ | |
54 | // 1.0 09/24/02 Created | |
55 | // | |
56 | // **************************************************************** | |
57 | ||
58 | ||
59 | ||
60 | module xpcs_rxio_sync_sm ( | |
61 | rx_lane_clk, | |
62 | rx_lane_reset, | |
63 | rx_signal_detect, | |
64 | ||
65 | byte_deskew, | |
66 | special_deskew, | |
67 | error_deskew, | |
68 | ||
69 | state, | |
70 | csr_lane_sync_status); | |
71 | ||
72 | input rx_lane_clk; | |
73 | input rx_lane_reset; | |
74 | input rx_signal_detect; | |
75 | ||
76 | input [7:0] byte_deskew; | |
77 | input special_deskew; | |
78 | input error_deskew; | |
79 | ||
80 | output [3:0] state; | |
81 | output csr_lane_sync_status; | |
82 | ||
83 | // Wires and Regs which are not flops | |
84 | ||
85 | wire com_det; | |
86 | wire [3:0] nxt_state; | |
87 | ||
88 | // Regs which are flops | |
89 | ||
90 | reg csr_lane_sync_status; | |
91 | wire rx_lane_sync_loss; | |
92 | ||
93 | wire inc_comma_cnt; | |
94 | wire inc_symbol_cnt; | |
95 | ||
96 | wire [2:0] nxt_comma_cnt; // counter for number of good commas received | |
97 | wire [2:0] nxt_symbol_cnt; // counter for number of good symbol received | |
98 | ||
99 | reg [2:0] comma_cnt; | |
100 | reg [2:0] symbol_cnt; | |
101 | ||
102 | wire clr_comma_cnt; | |
103 | wire clr_symbol_cnt; | |
104 | ||
105 | wire comma_cnt_eq4; | |
106 | wire symbol_cnt_eq3; | |
107 | ||
108 | reg [3:0] state; | |
109 | ||
110 | wire com_k281_det; | |
111 | wire com_k285_det; | |
112 | wire com_k287_det; | |
113 | ||
114 | wire invalid; | |
115 | ||
116 | ||
117 | parameter LOSS_SYNC = 4'h0; // word synchronization state machine | |
118 | parameter IN_SYNC = 4'h1; | |
119 | parameter ONE_INVALID = 4'h2; | |
120 | parameter TWO_INVALID = 4'h4; | |
121 | parameter THREE_INVALID = 4'h8; | |
122 | ||
123 | ||
124 | // Decode | |
125 | /* | |
126 | XPCS_DEC_COM 10'h1BC // K28.5 | |
127 | XPCS_DEC_281 10'h13C | |
128 | XPCS_DEC_285 10'h1BC | |
129 | XPCS_DEC_287 10'h1FC | |
130 | ||
131 | XPCS_DEC_SDP 10'h1FB | |
132 | XPCS_DEC_SLP 10'h15C | |
133 | XPCS_DEC_EGP 10'h1FD | |
134 | XPCS_DEC_EBP 10'h1FE | |
135 | XPCS_DEC_PAD 10'h1F7 | |
136 | XPCS_DEC_SKP 10'h11C | |
137 | ||
138 | XPCS_DEC_LN0 10'h000 | |
139 | XPCS_DEC_LN1 10'h001 | |
140 | XPCS_DEC_LN2 10'h002 | |
141 | XPCS_DEC_LN3 10'h004 | |
142 | ||
143 | XPCS_DEC_LN4 10'h008 | |
144 | XPCS_DEC_LN5 10'h00F | |
145 | XPCS_DEC_LN6 10'h010 | |
146 | XPCS_DEC_LN7 10'h017 | |
147 | XPCS_DEC_LN8 10'h018 | |
148 | XPCS_DEC_LN9 10'h01B | |
149 | XPCS_DEC_LNA 10'h01D | |
150 | XPCS_DEC_LNB 10'h01E | |
151 | */ | |
152 | ||
153 | assign com_k281_det = ({error_deskew,special_deskew,byte_deskew[7:0]} == `XPCS_DEC_281); | |
154 | assign com_k285_det = ({error_deskew,special_deskew,byte_deskew[7:0]} == `XPCS_DEC_285); | |
155 | assign com_k287_det = ({error_deskew,special_deskew,byte_deskew[7:0]} == `XPCS_DEC_287); | |
156 | ||
157 | ||
158 | assign com_det = com_k281_det | com_k285_det | com_k287_det; | |
159 | ||
160 | assign invalid = error_deskew; // Disparity and decode errors | |
161 | ||
162 | ||
163 | /* | |
164 | ** Synchronization COMMA counter | |
165 | */ | |
166 | ||
167 | always @ (posedge rx_lane_clk) | |
168 | if (rx_lane_reset) | |
169 | comma_cnt <= 3'b0; | |
170 | else | |
171 | comma_cnt <= nxt_comma_cnt; | |
172 | ||
173 | assign nxt_comma_cnt = (rx_lane_reset | clr_comma_cnt) ? 3'h0 : | |
174 | (inc_comma_cnt) ? comma_cnt + 3'h1 : | |
175 | comma_cnt; | |
176 | ||
177 | assign comma_cnt_eq4 = (comma_cnt >= 3'h4); | |
178 | ||
179 | /* | |
180 | ** Synchronization SYMBOL counter | |
181 | */ | |
182 | ||
183 | always @ (posedge rx_lane_clk) | |
184 | if (rx_lane_reset) | |
185 | symbol_cnt <= 3'b0; | |
186 | else | |
187 | symbol_cnt <= nxt_symbol_cnt; | |
188 | ||
189 | assign nxt_symbol_cnt = (rx_lane_reset | clr_symbol_cnt) ? 3'h0 : | |
190 | (inc_symbol_cnt) ? symbol_cnt + 3'h1 : | |
191 | symbol_cnt; | |
192 | ||
193 | assign symbol_cnt_eq3 = (symbol_cnt >= 3'h3); | |
194 | ||
195 | /* ************************************************************* */ | |
196 | ||
197 | always @ (posedge rx_lane_clk) | |
198 | csr_lane_sync_status <= !rx_lane_sync_loss; | |
199 | ||
200 | /* | |
201 | ** Call of function word synchronization | |
202 | */ | |
203 | ||
204 | assign {rx_lane_sync_loss,inc_symbol_cnt,clr_symbol_cnt,inc_comma_cnt,clr_comma_cnt,nxt_state} | |
205 | = synchronization_fn(rx_lane_reset, | |
206 | com_det, | |
207 | invalid, | |
208 | comma_cnt_eq4, | |
209 | symbol_cnt_eq3, | |
210 | state); | |
211 | ||
212 | ||
213 | /* | |
214 | ** Word Synchronization state machine | |
215 | */ | |
216 | function [8:0] synchronization_fn; | |
217 | input f_reset; | |
218 | input f_com_det; // to determine if there is a comma | |
219 | input f_invalid; // invalid transmission word detected | |
220 | input f_comma_cnt_eq4; | |
221 | input f_symbol_cnt_eq3; // found 3 commas with no errors | |
222 | input [3:0] state; | |
223 | ||
224 | reg f_loss_sync; // indicates word sync status | |
225 | reg f_inc_comma_cnt; // increment word sync counter | |
226 | reg f_clr_comma_cnt; // clear word sync counter | |
227 | reg f_inc_symbol_cnt; // increment word sync counter | |
228 | reg f_clr_symbol_cnt; // clear word sync counter | |
229 | reg [3:0] n_state; // next state | |
230 | ||
231 | begin | |
232 | if (f_reset) | |
233 | begin | |
234 | f_loss_sync = 1'h1; | |
235 | f_inc_comma_cnt = 1'h0; | |
236 | f_clr_comma_cnt = 1'h1; | |
237 | f_inc_symbol_cnt = 1'h0; | |
238 | f_clr_symbol_cnt = 1'h1; | |
239 | n_state = LOSS_SYNC; | |
240 | end | |
241 | else | |
242 | begin | |
243 | f_loss_sync = 1'h0; | |
244 | f_inc_comma_cnt = 1'h0; | |
245 | f_clr_comma_cnt = 1'h0; | |
246 | f_inc_symbol_cnt = 1'h0; | |
247 | f_clr_symbol_cnt = 1'h0; | |
248 | n_state = LOSS_SYNC; | |
249 | ||
250 | case (state) // synopsys parallel_case | |
251 | ||
252 | LOSS_SYNC : // 0 // being in this state triggers link config | |
253 | begin | |
254 | f_loss_sync = 1'h1; | |
255 | if (f_reset) | |
256 | n_state = LOSS_SYNC; | |
257 | else if (f_invalid) | |
258 | begin | |
259 | f_clr_comma_cnt = 1'h1; | |
260 | f_clr_symbol_cnt = 1'h1; | |
261 | n_state = LOSS_SYNC; | |
262 | end | |
263 | else if (f_comma_cnt_eq4) // got 3 good commas | |
264 | n_state = IN_SYNC; | |
265 | else if (f_com_det) // accum good | |
266 | begin | |
267 | f_clr_comma_cnt = 1'h0; | |
268 | f_inc_comma_cnt = 1'h1; | |
269 | n_state = LOSS_SYNC; | |
270 | end | |
271 | else | |
272 | n_state = LOSS_SYNC; | |
273 | ||
274 | end | |
275 | ||
276 | IN_SYNC : // 1 | |
277 | if (f_invalid) | |
278 | begin | |
279 | f_clr_comma_cnt = 1'h1; | |
280 | f_clr_symbol_cnt = 1'h1; | |
281 | n_state = ONE_INVALID; | |
282 | end | |
283 | else | |
284 | n_state = IN_SYNC; | |
285 | ||
286 | ONE_INVALID : // 2 | |
287 | if (f_invalid) | |
288 | begin | |
289 | f_clr_symbol_cnt = 1'h1; | |
290 | f_clr_comma_cnt = 1'h1; | |
291 | n_state = TWO_INVALID; | |
292 | end | |
293 | ||
294 | else if (f_symbol_cnt_eq3) // got 3 good symbols | |
295 | begin | |
296 | f_clr_symbol_cnt = 1'h1; | |
297 | f_clr_comma_cnt = 1'h1; | |
298 | n_state = IN_SYNC; // go to sync state | |
299 | end | |
300 | ||
301 | else // inc good symbol count | |
302 | begin | |
303 | f_clr_symbol_cnt = 1'h0; | |
304 | f_inc_symbol_cnt = 1'h1; | |
305 | n_state = ONE_INVALID; | |
306 | end | |
307 | ||
308 | ||
309 | TWO_INVALID : // 4 | |
310 | if (f_invalid) | |
311 | begin | |
312 | f_clr_symbol_cnt = 1'h1; | |
313 | f_clr_comma_cnt = 1'h1; | |
314 | n_state = THREE_INVALID; | |
315 | end | |
316 | ||
317 | else if (f_symbol_cnt_eq3) // got 3 good symbols | |
318 | begin | |
319 | f_clr_symbol_cnt = 1'h1; | |
320 | f_clr_comma_cnt = 1'h1; | |
321 | n_state = ONE_INVALID; // Need to get 3 more good symbols | |
322 | end | |
323 | ||
324 | else // inc good symbol count | |
325 | begin | |
326 | f_clr_symbol_cnt = 1'h0; | |
327 | f_inc_symbol_cnt = 1'h1; | |
328 | n_state = TWO_INVALID; | |
329 | end | |
330 | ||
331 | ||
332 | THREE_INVALID : // 8 | |
333 | if (f_invalid) | |
334 | begin | |
335 | f_clr_symbol_cnt = 1'h1; | |
336 | f_clr_comma_cnt = 1'h1; | |
337 | n_state = LOSS_SYNC; | |
338 | end | |
339 | ||
340 | else if (f_symbol_cnt_eq3) // got 3 good symbols | |
341 | begin | |
342 | f_clr_symbol_cnt = 1'h1; | |
343 | f_clr_comma_cnt = 1'h1; | |
344 | n_state = TWO_INVALID; // Need to get 6 more good symbols | |
345 | end | |
346 | ||
347 | else // inc good symbol count | |
348 | begin | |
349 | f_clr_symbol_cnt = 1'h0; | |
350 | f_inc_symbol_cnt = 1'h1; | |
351 | n_state = THREE_INVALID; | |
352 | end | |
353 | ||
354 | ||
355 | endcase | |
356 | ||
357 | end | |
358 | // {rx_lane_sync_loss, inc_symbol_cnt, clr_symbol_cnt, inc_comma_cnt, clr_comma_cnt,nxt_state} | |
359 | synchronization_fn = {f_loss_sync,f_inc_symbol_cnt,f_clr_symbol_cnt,f_inc_comma_cnt,f_clr_comma_cnt,n_state}; | |
360 | ||
361 | end | |
362 | endfunction | |
363 | ||
364 | // ******************************** | |
365 | // Receive State Machine Registers | |
366 | // ******************************** | |
367 | ||
368 | always @(posedge rx_lane_clk) | |
369 | if (rx_lane_reset | !rx_signal_detect) | |
370 | begin | |
371 | state <= 4'b0; | |
372 | end | |
373 | else | |
374 | begin | |
375 | state <= nxt_state; | |
376 | end | |
377 | ||
378 | // 0in bits_on -var state -max 1 -clock rx_lane_clk | |
379 | ||
380 | // 0in state -var state -val LOSS_SYNC -next IN_SYNC -clock rx_lane_clk -reset (rx_lane_reset | !rx_signal_detect) | |
381 | // 0in state -var state -val IN_SYNC -next ONE_INVALID -clock rx_lane_clk -reset (rx_lane_reset | !rx_signal_detect) | |
382 | // 0in state -var state -val ONE_INVALID -next TWO_INVALID IN_SYNC -clock rx_lane_clk -reset (rx_lane_reset | !rx_signal_detect) | |
383 | // 0in state -var state -val TWO_INVALID -next THREE_INVALID ONE_INVALID -clock rx_lane_clk -reset (rx_lane_reset | !rx_signal_detect) | |
384 | // 0in state -var state -val THREE_INVALID -next LOSS_SYNC TWO_INVALID -clock rx_lane_clk -reset (rx_lane_reset | !rx_signal_detect) | |
385 | ||
386 | endmodule |