Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / xpcs_rx.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: xpcs_rx.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 Receive
41// Block: XPCS
42// Author: Carlos Castil
43//
44// Module: xpcs_rx
45// File: xpcs_rx.v
46//
47// Description: Logic to deliver receive data to the Vega core
48// in single clock XGMII, 8 byte wide on a single
49// clock.
50//
51// Revision History
52// ------------------------------------------------------------
53// Ver Date Comments
54// ------------------------------------------------------------
55// 1.0 10/16/02 Created
56//
57// ****************************************************************
58
59
60
61module xpcs_rx (
62 rx_clk,
63 reset_rxclk,
64
65 xserdes_rdy,
66
67 state,
68
69 csr_xpcs_enable,
70 csr_link_status_rx,
71 csr_tx_test_enable,
72
73 csr_receive_fault_ref,
74
75 inc_rx_pkt_count_ref,
76
77 rx_byte_0,
78 rx_byte_1,
79 rx_byte_2,
80 rx_byte_3,
81
82 rx_special_0,
83 rx_special_1,
84 rx_special_2,
85 rx_special_3,
86
87 rx_error_0,
88 rx_error_1,
89 rx_error_2,
90 rx_error_3,
91
92 rx_xgmii_byte_0,
93 rx_xgmii_byte_1,
94 rx_xgmii_byte_2,
95 rx_xgmii_byte_3,
96
97 rx_xgmii_special_0,
98 rx_xgmii_special_1,
99 rx_xgmii_special_2,
100 rx_xgmii_special_3
101
102 );
103
104input rx_clk;
105input reset_rxclk;
106
107input xserdes_rdy;
108
109input csr_xpcs_enable;
110input csr_link_status_rx;
111input csr_tx_test_enable;
112
113input [7:0] rx_byte_0;
114input [7:0] rx_byte_1;
115input [7:0] rx_byte_2;
116input [7:0] rx_byte_3;
117
118input rx_special_0;
119input rx_special_1;
120input rx_special_2;
121input rx_special_3;
122
123input rx_error_0;
124input rx_error_1;
125input rx_error_2;
126input rx_error_3;
127
128output state;
129
130output [7:0] rx_xgmii_byte_0;
131output [7:0] rx_xgmii_byte_1;
132output [7:0] rx_xgmii_byte_2;
133output [7:0] rx_xgmii_byte_3;
134
135output rx_xgmii_special_0;
136output rx_xgmii_special_1;
137output rx_xgmii_special_2;
138output rx_xgmii_special_3;
139
140output inc_rx_pkt_count_ref;
141
142output csr_receive_fault_ref;
143
144parameter FAULT = 1'b0;
145parameter RECEIVE = 1'b1;
146
147wire nxt_state;
148
149wire serdes_rdy;
150
151wire detect_idle_0;
152wire detect_idle_1;
153wire detect_idle_2;
154wire detect_idle_3;
155
156// vlint flag_dangling_net_within_module off
157// vlint flag_net_has_no_load off
158wire detect_idle;
159wire detect_sop_pipe;
160// vlint flag_dangling_net_within_module on
161// vlint flag_net_has_no_load on
162
163reg state;
164
165reg [7:0] rx_xgmii_byte_0;
166reg [7:0] rx_xgmii_byte_1;
167reg [7:0] rx_xgmii_byte_2;
168reg [7:0] rx_xgmii_byte_3;
169
170reg rx_xgmii_special_0;
171reg rx_xgmii_special_1;
172reg rx_xgmii_special_2;
173reg rx_xgmii_special_3;
174
175reg [7:0] rx_byte_pipe_0;
176reg [7:0] rx_byte_pipe_1;
177reg [7:0] rx_byte_pipe_2;
178reg [7:0] rx_byte_pipe_3;
179
180reg rx_error_int_0;
181reg rx_error_int_1;
182reg rx_error_int_2;
183reg rx_error_int_3;
184
185reg rx_special_pipe_0;
186reg rx_special_pipe_1;
187reg rx_special_pipe_2;
188reg rx_special_pipe_3;
189
190wire rx_error_pipe_0;
191wire rx_error_pipe_1;
192wire rx_error_pipe_2;
193wire rx_error_pipe_3;
194
195wire detect_eop_0;
196wire detect_eop_1;
197wire detect_eop_2;
198wire detect_eop_3;
199
200wire detect_eop;
201
202wire detect_seq;
203
204wire detect_eop_pipe;
205
206wire detect_eop_pipe0;
207wire detect_eop_pipe1;
208wire detect_eop_pipe2;
209wire detect_eop_pipe3;
210
211wire xpcs_enable;
212wire tx_test_enable;
213
214/* ********************************************************* */
215/* Synchronize */
216/* ********************************************************* */
217
218SYNC_CELL u_sync_serdes_rdy (
219 .D (xserdes_rdy), // unsynchronized
220 .CP (rx_clk),
221 .Q (serdes_rdy)); // synchronized
222
223SYNC_CELL u_sync_xpcs_enable (
224 .D (csr_xpcs_enable), // unsynchronized
225 .CP (rx_clk),
226 .Q (xpcs_enable)); // synchronized
227
228SYNC_CELL u_sync_test_enable (
229 .D (csr_tx_test_enable), // unsynchronized
230 .CP (rx_clk),
231 .Q (tx_test_enable)); // synchronized
232
233/* ********************************************************************** */
234/* Pipeline to satisfy 48.2.6.1.4 check_end Function */
235/* ********************************************************************** */
236
237assign detect_eop_0 = ({rx_error_0,rx_special_0,rx_byte_0} == `XPCS_DEC_END);
238assign detect_eop_1 = ({rx_error_1,rx_special_1,rx_byte_1} == `XPCS_DEC_END);
239assign detect_eop_2 = ({rx_error_2,rx_special_2,rx_byte_2} == `XPCS_DEC_END);
240assign detect_eop_3 = ({rx_error_3,rx_special_3,rx_byte_3} == `XPCS_DEC_END);
241
242assign detect_eop = detect_eop_0 | detect_eop_1 | detect_eop_2 | detect_eop_3;
243
244always @ (posedge rx_clk)
245 if (reset_rxclk)
246 begin
247 rx_byte_pipe_0 <= 8'h00;
248 rx_byte_pipe_1 <= 8'h00;
249 rx_byte_pipe_2 <= 8'h00;
250 rx_byte_pipe_3 <= 8'h00;
251 end
252 else
253 begin
254 rx_byte_pipe_0 <= rx_byte_0;
255 rx_byte_pipe_1 <= rx_byte_1;
256 rx_byte_pipe_2 <= rx_byte_2;
257 rx_byte_pipe_3 <= rx_byte_3;
258 end
259
260always @ (posedge rx_clk)
261 if (reset_rxclk)
262 begin
263 rx_error_int_0 <= 1'b0;
264 rx_error_int_1 <= 1'b0;
265 rx_error_int_2 <= 1'b0;
266 rx_error_int_3 <= 1'b0;
267 end
268 else
269 begin
270 rx_error_int_0 <= rx_error_0;
271 rx_error_int_1 <= rx_error_1;
272 rx_error_int_2 <= rx_error_2;
273 rx_error_int_3 <= rx_error_3;
274 end
275
276assign rx_error_pipe_0 = rx_error_int_0 | rx_error_0 & detect_eop_pipe | rx_error_0 & detect_eop;
277assign rx_error_pipe_1 = rx_error_int_1 | rx_error_1 & detect_eop_pipe | rx_error_1 & detect_eop;
278assign rx_error_pipe_2 = rx_error_int_2 | rx_error_2 & detect_eop_pipe | rx_error_2 & detect_eop;
279assign rx_error_pipe_3 = rx_error_int_3 | rx_error_3 & detect_eop_pipe | rx_error_3 & detect_eop;
280
281always @ (posedge rx_clk)
282 if (reset_rxclk)
283 begin
284 rx_special_pipe_0 <= 1'b0;
285 rx_special_pipe_1 <= 1'b0;
286 rx_special_pipe_2 <= 1'b0;
287 rx_special_pipe_3 <= 1'b0;
288 end
289 else
290 begin
291 rx_special_pipe_0 <= rx_special_0;
292 rx_special_pipe_1 <= rx_special_1;
293 rx_special_pipe_2 <= rx_special_2;
294 rx_special_pipe_3 <= rx_special_3;
295 end
296
297/* ********************************************************************** */
298
299assign detect_eop_pipe0 = ({rx_error_int_0,rx_special_pipe_0,rx_byte_pipe_0} == `XPCS_DEC_END);
300assign detect_eop_pipe1 = ({rx_error_int_1,rx_special_pipe_1,rx_byte_pipe_1} == `XPCS_DEC_END);
301assign detect_eop_pipe2 = ({rx_error_int_2,rx_special_pipe_2,rx_byte_pipe_2} == `XPCS_DEC_END);
302assign detect_eop_pipe3 = ({rx_error_int_3,rx_special_pipe_3,rx_byte_pipe_3} == `XPCS_DEC_END);
303
304assign detect_idle_0 = ({rx_error_pipe_0,rx_special_pipe_0,rx_byte_pipe_0} == `XPCS_DEC_SKP) |
305 ({rx_error_pipe_0,rx_special_pipe_0,rx_byte_pipe_0} == `XPCS_DEC_ALG) |
306 ({rx_error_pipe_0,rx_special_pipe_0,rx_byte_pipe_0} == `XPCS_DEC_COM);
307
308assign detect_idle_1 = ({rx_error_pipe_1,rx_special_pipe_1,rx_byte_pipe_1} == `XPCS_DEC_SKP) |
309 ({rx_error_pipe_1,rx_special_pipe_1,rx_byte_pipe_1} == `XPCS_DEC_ALG) |
310 ({rx_error_pipe_1,rx_special_pipe_1,rx_byte_pipe_1} == `XPCS_DEC_COM);
311
312assign detect_idle_2 = ({rx_error_pipe_2,rx_special_pipe_2,rx_byte_pipe_2} == `XPCS_DEC_SKP) |
313 ({rx_error_pipe_2,rx_special_pipe_2,rx_byte_pipe_2} == `XPCS_DEC_ALG) |
314 ({rx_error_pipe_2,rx_special_pipe_2,rx_byte_pipe_2} == `XPCS_DEC_COM);
315
316assign detect_idle_3 = ({rx_error_pipe_3,rx_special_pipe_3,rx_byte_pipe_3} == `XPCS_DEC_SKP) |
317 ({rx_error_pipe_3,rx_special_pipe_3,rx_byte_pipe_3} == `XPCS_DEC_ALG) |
318 ({rx_error_pipe_3,rx_special_pipe_3,rx_byte_pipe_3} == `XPCS_DEC_COM);
319
320/* 0in req_ack -req $0in_rising_edge(detect_sop_pipe) -ack $0in_rising_edge(detect_eop_pipe) -clock rx_clk -max 7000 */
321
322assign detect_eop_pipe = (detect_eop_pipe0 | detect_eop_pipe1 | detect_eop_pipe2 | detect_eop_pipe3);
323assign detect_sop_pipe = ({rx_error_pipe_0,rx_special_pipe_0,rx_byte_pipe_0} == `XPCS_DEC_SDP);
324
325assign detect_idle = (detect_idle_0 | detect_idle_1 | detect_idle_2 | detect_idle_3);
326assign detect_seq = ({rx_error_pipe_0,rx_special_pipe_0,rx_byte_pipe_0} == `XPCS_DEC_SEQ);
327
328assign inc_rx_pkt_count_ref = detect_eop_pipe;
329
330assign csr_receive_fault_ref = detect_seq;
331
332
333
334always @ (posedge rx_clk)
335 if (reset_rxclk)
336 begin
337 rx_xgmii_byte_0 <= 8'h9C;
338 rx_xgmii_byte_1 <= 8'h00;
339 rx_xgmii_byte_2 <= 8'h00;
340 rx_xgmii_byte_3 <= 8'h00;
341 end
342 else
343 begin
344
345 rx_xgmii_byte_3 <= (state == FAULT) ? 8'h01 :
346 ((state == RECEIVE) & rx_error_pipe_3) & !detect_eop_pipe3 ? 8'hFE :
347 detect_idle_3 & rx_special_pipe_3 & !detect_eop_pipe3 ? 8'h07 :
348 detect_eop_pipe & !detect_eop_pipe3 ? 8'h07 :
349 rx_byte_pipe_3 ;
350
351 rx_xgmii_byte_2 <= (state == FAULT) ? 8'h00 :
352 ((state == RECEIVE) & rx_error_pipe_2) & !detect_eop_pipe2 ? 8'hFE :
353 detect_idle_2 & rx_special_pipe_2 & !detect_eop_pipe2 ? 8'h07 :
354 (detect_eop_pipe & !(detect_eop_pipe3 | detect_eop_pipe2)) ? 8'h07 :
355 rx_byte_pipe_2 ;
356
357 rx_xgmii_byte_1 <= (state == FAULT) ? 8'h00 :
358 ((state == RECEIVE) & rx_error_pipe_1) & !detect_eop_pipe1 ? 8'hFE :
359 detect_idle_1 & rx_special_pipe_1 & !detect_eop_pipe1 ? 8'h07 :
360 (detect_eop_pipe & !(detect_eop_pipe3 | detect_eop_pipe2 | detect_eop_pipe1)) ? 8'h07 :
361 rx_byte_pipe_1 ;
362
363 rx_xgmii_byte_0 <= (state == FAULT) ? 8'h9C :
364 ((state == RECEIVE) & rx_error_pipe_0) & !detect_eop_pipe0 ? 8'hFE :
365 detect_idle_0 & rx_special_pipe_0 & !detect_eop_pipe0 ? 8'h07 :
366 rx_byte_pipe_0 ;
367 end
368
369
370always @ (posedge rx_clk)
371 if (reset_rxclk)
372 begin
373 rx_xgmii_special_0 <= 1'b1;
374 rx_xgmii_special_1 <= 1'b0;
375 rx_xgmii_special_2 <= 1'b0;
376 rx_xgmii_special_3 <= 1'b0;
377 end
378 else
379 begin
380 rx_xgmii_special_3 <= (state == FAULT) ? 1'b0 : rx_special_pipe_3 | ((state == RECEIVE) & rx_error_pipe_3) ;
381 rx_xgmii_special_2 <= (state == FAULT) ? 1'b0 : rx_special_pipe_2 | ((state == RECEIVE) & rx_error_pipe_2) ;
382 rx_xgmii_special_1 <= (state == FAULT) ? 1'b0 : rx_special_pipe_1 | ((state == RECEIVE) & rx_error_pipe_1) ;
383 rx_xgmii_special_0 <= (state == FAULT) ? 1'b1 : rx_special_pipe_0 | ((state == RECEIVE) & rx_error_pipe_0) ;
384 end
385
386
387assign {nxt_state} = receive_fn (reset_rxclk,
388 serdes_rdy,
389 tx_test_enable,
390 xpcs_enable,
391 csr_link_status_rx,
392 detect_eop_pipe,
393 state);
394
395
396function [0:0] receive_fn;
397
398 input reset;
399 input serdes_rdy;
400 input tx_test_enable;
401 input enable;
402 input link;
403 input eop;
404 input state;
405
406 reg n_state;
407
408 begin
409
410 if (reset)
411
412 begin
413 n_state = FAULT;
414 end
415
416 else
417
418 begin
419
420 n_state = FAULT;
421
422 case (state)
423
424 FAULT :
425 if (link & enable & serdes_rdy & !tx_test_enable)
426 n_state = RECEIVE;
427 else
428 n_state = FAULT;
429
430 RECEIVE:
431 if (!link | tx_test_enable)
432 n_state = FAULT;
433 else if (!enable & eop)
434 n_state = FAULT;
435 else
436 n_state = RECEIVE;
437
438 endcase
439
440 end
441
442 receive_fn = {n_state};
443
444 end
445
446endfunction
447
448// 0in state -var state -val FAULT -next RECEIVE -clock rx_clk
449// 0in state -var state -val RECEIVE -next FAULT -clock rx_clk
450
451
452always @ (posedge rx_clk)
453 if (reset_rxclk)
454 state <= 1'b0;
455 else
456 state <= nxt_state;
457
458
459
460endmodule