Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / xpcs_rxio_ebuffer.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: xpcs_rxio_ebuffer.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 Physical Interface Core
41// Block: 10G Ethernet Physical Interface Controller
42// Author: Carlos Castil
43//
44// Module: xpcs_rxio_ebuffer
45// File: xpcs_rxio_ebuffer.v
46//
47// Description:
48// This block contains an elastic buffer and deskew controller
49// for ieee 802.3ae xpcs clock tolerance compensation.
50//
51// Revision History
52// ------------------------------------------------------------
53// Ver Date Comments
54// ------------------------------------------------------------
55// 1.0 10/9/02 Created
56//
57// ****************************************************************
58
59
60
61module xpcs_rxio_ebuffer (
62 rx_clk,
63 reset,
64
65 w_byte_0,
66 w_byte_1,
67 w_byte_2,
68 w_byte_3,
69
70 w_special_0,
71 w_special_1,
72 w_special_2,
73 w_special_3,
74
75 w_error_0,
76 w_error_1,
77 w_error_2,
78 w_error_3,
79
80 flush,
81
82 w_hold_0,
83 w_hold_1,
84 w_hold_2,
85 w_hold_3,
86
87 csr_link_status,
88 sync_status,
89
90 csr_pulse_deskew_error,
91 csr_ebuffer_state,
92
93 r_byte_0,
94 r_byte_1,
95 r_byte_2,
96 r_byte_3,
97
98 r_special_0,
99 r_special_1,
100 r_special_2,
101 r_special_3,
102
103 r_error_0,
104 r_error_1,
105 r_error_2,
106 r_error_3 );
107
108
109input rx_clk;
110input reset;
111
112input sync_status;
113
114input [7:0] w_byte_0;
115input [7:0] w_byte_1;
116input [7:0] w_byte_2;
117input [7:0] w_byte_3;
118
119input w_special_0;
120input w_special_1;
121input w_special_2;
122input w_special_3;
123
124input w_error_0;
125input w_error_1;
126input w_error_2;
127input w_error_3;
128
129output flush;
130
131output w_hold_0;
132output w_hold_1;
133output w_hold_2;
134output w_hold_3;
135
136output csr_link_status;
137output [7:0] csr_ebuffer_state;
138output csr_pulse_deskew_error;
139
140output [7:0] r_byte_0;
141output [7:0] r_byte_1;
142output [7:0] r_byte_2;
143output [7:0] r_byte_3;
144
145output r_special_0;
146output r_special_1;
147output r_special_2;
148output r_special_3;
149
150output r_error_0;
151output r_error_1;
152output r_error_2;
153output r_error_3;
154
155// Write Clock Domain Wires And Regs Which Are Not Flops
156
157wire hold_en;
158
159// State Machine control signals
160
161reg [2:0] flush_cnt;
162
163reg [2:0] deskew_cnt;
164reg deskew_ack;
165reg deskew_req;
166
167wire deskew_done;
168wire deskew_init;
169
170wire dec_flush_cnt;
171
172reg flush_int;
173reg flush_reg;
174
175reg deskew_ack_hold;
176reg deskew_req_hold;
177
178reg det_alg;
179reg deskewing_reg;
180
181wire deskewing;
182wire deskew_on_pulse;
183wire deskew_off_pulse;
184
185wire det_alg_x4;
186
187wire det_alg_lane0;
188wire det_alg_lane1;
189wire det_alg_lane2;
190wire det_alg_lane3;
191
192reg [9:0] w_s_in_0;
193reg [9:0] w_s_in_1;
194reg [9:0] w_s_in_2;
195reg [9:0] w_s_in_3;
196
197// ************************************************************************
198// Align character detect logic
199// ************************************************************************
200
201// Register inputs from the deskew fifo
202
203always @ (posedge rx_clk)
204 begin
205 w_s_in_0[9:0] <= {w_error_0, w_special_0, w_byte_0[7:0]};
206 w_s_in_1[9:0] <= {w_error_1, w_special_1, w_byte_1[7:0]};
207 w_s_in_2[9:0] <= {w_error_2, w_special_2, w_byte_2[7:0]};
208 w_s_in_3[9:0] <= {w_error_3, w_special_3, w_byte_3[7:0]};
209 end
210
211
212assign det_alg_lane0 = ({w_error_0, w_special_0, w_byte_0[7:0]} == `XPCS_DEC_ALG) ;
213assign det_alg_lane1 = ({w_error_1, w_special_1, w_byte_1[7:0]} == `XPCS_DEC_ALG) ;
214assign det_alg_lane2 = ({w_error_2, w_special_2, w_byte_2[7:0]} == `XPCS_DEC_ALG) ;
215assign det_alg_lane3 = ({w_error_3, w_special_3, w_byte_3[7:0]} == `XPCS_DEC_ALG) ;
216
217// deskewing starts after detection of any align character in any lane
218
219always @ (posedge rx_clk)
220 det_alg <= (det_alg_lane0 | det_alg_lane1 | det_alg_lane2 | det_alg_lane3);
221
222always @ (posedge rx_clk)
223 if (reset)
224 deskewing_reg <= 1'b0;
225 else
226 deskewing_reg <= deskew_off_pulse ? 1'b0 : deskew_on_pulse ? 1'b1 : deskewing;
227
228assign deskew_off_pulse = (deskew_cnt[2:0] == 3'b000);
229assign deskew_on_pulse = (flush_cnt[2:0] == 3'b000) &
230 (det_alg_lane0 | det_alg_lane1 | det_alg_lane2 | det_alg_lane3) & !det_alg;
231
232assign deskewing = deskew_on_pulse | deskewing_reg;
233
234
235// assign hold_en = (deskew_cnt[2:0] != 3'b000) & deskewing & !det_alg_x4 ;
236
237// deskew_cnt <= flush_reg ? 3'b100 : hold_en ? (deskew_cnt - 3'b001) : 3'b000;
238
239
240
241
242// *********************************************************************
243// Deskew Logic
244// *********************************************************************
245
246assign det_alg_x4 = det_alg_lane0 &
247 det_alg_lane1 &
248 det_alg_lane2 &
249 det_alg_lane3;
250
251
252// *********************************************************************
253// Deskew fifo control logic
254// *********************************************************************
255
256// Assert hold if deskewing and alignment detected on at least one lane
257
258assign w_hold_0 = (hold_en & det_alg_lane0);
259assign w_hold_1 = (hold_en & det_alg_lane1);
260assign w_hold_2 = (hold_en & det_alg_lane2);
261assign w_hold_3 = (hold_en & det_alg_lane3);
262
263// ----------------------------
264// Elastic Buffer output wires
265// ----------------------------
266
267assign {r_error_0,r_special_0,r_byte_0[7:0]} = w_s_in_0[9:0];
268assign {r_error_1,r_special_1,r_byte_1[7:0]} = w_s_in_1[9:0];
269assign {r_error_2,r_special_2,r_byte_2[7:0]} = w_s_in_2[9:0];
270assign {r_error_3,r_special_3,r_byte_3[7:0]} = w_s_in_3[9:0];
271
272
273// *********************************
274// Deskew init and Deskew done logic
275// *********************************
276
277// Generate deskew request
278
279always @ (posedge rx_clk)
280 if (reset)
281 deskew_req <= 1'b0;
282 else
283 deskew_req <= deskew_init ? !deskew_req : deskew_req;
284
285// Generate pulse to flush deskew fifos and reset deskew_cnt
286
287always @ (posedge rx_clk)
288 if (reset)
289 deskew_req_hold <= 1'b0;
290 else
291 deskew_req_hold <= deskew_req;
292
293
294assign flush = (deskew_req ^ deskew_req_hold);
295
296// Generate flush_int used to create deskew_ack
297
298always @ (posedge rx_clk)
299 if (reset)
300 begin
301 flush_reg <= 1'b0;
302 flush_int <= 1'b0;
303 end
304 else
305 begin
306 flush_reg <= flush;
307 flush_int <= flush_reg ? 1'b1 : (deskew_cnt[2:0]==3'b000) ? 1'b0 : flush_int ;
308 end
309
310// Count from 6, 5, 4, 3, 2, 1, to 0.... 5 clock count to account for deskew of
311// 5 X 6.4 ns = 32 ns deskew window
312
313always @ (posedge rx_clk)
314 if (reset)
315 begin
316 deskew_cnt <= 3'b000;
317 end
318 else
319 begin
320 deskew_cnt <= flush_reg ? 3'b100 : hold_en ? (deskew_cnt - 3'b001) : deskew_cnt;
321 end
322
323// Wait for flush to complete to enable hold....fifo must flush
324
325always @ (posedge rx_clk)
326 if (reset)
327 begin
328 flush_cnt <= 3'b000;
329 end
330 else
331 begin
332 flush_cnt <= flush_reg ? 3'b100 : (dec_flush_cnt) ? (flush_cnt - 3'b001) : 3'b000;
333 end
334
335assign dec_flush_cnt = (flush_cnt != 3'b000);
336
337
338// hold if counter is not expired and commas have not been detected across all lanes
339// Deskewing starts immidiately on detection of an align character.
340
341assign hold_en = (deskew_cnt[2:0] != 3'b000) & deskewing & !det_alg_x4 ;
342
343
344// Generate acknowledge signal for deskew process
345
346always @ (posedge rx_clk)
347 if (reset)
348 deskew_ack <= 1'b0;
349 else
350 deskew_ack <= (flush_int & (deskew_cnt[2:0]==3'b000)) ? deskew_req : deskew_ack ;
351
352// Generate deskew done strobe from edge of deskew_ack
353
354always @ (posedge rx_clk)
355 if (reset)
356 deskew_ack_hold <= 1'b0;
357 else
358 deskew_ack_hold <= deskew_ack;
359
360assign deskew_done = (deskew_ack_hold ^ deskew_ack);
361
362
363// ******************************************************************
364// Elastic Buffer state machine
365// ******************************************************************
366
367xpcs_rxio_ebuffer_sm xpcs_rxio_ebuffer_sm (
368 .reset(reset),
369 .rx_clk(rx_clk),
370
371 .csr_link_status(csr_link_status),
372
373 .csr_pulse_deskew_error(csr_pulse_deskew_error),
374 .sync_status(sync_status),
375
376 .state(csr_ebuffer_state),
377
378 .deskew_init(deskew_init),
379 .deskew_done(deskew_done),
380
381 .r_byte_0(r_byte_0),
382 .r_byte_1(r_byte_1),
383 .r_byte_2(r_byte_2),
384 .r_byte_3(r_byte_3),
385
386 .r_special_0(r_special_0),
387 .r_special_1(r_special_1),
388 .r_special_2(r_special_2),
389 .r_special_3(r_special_3),
390
391 .r_error_0(r_error_0),
392 .r_error_1(r_error_1),
393 .r_error_2(r_error_2),
394 .r_error_3(r_error_3) );
395
396
397
398endmodule