Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / pcs_rx_ctrl.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: pcs_rx_ctrl.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// @(#)pcs_rx_ctrl.v 1.1G
36/**********************************************************************/
37/* Project Name : CASSINI */
38/* Module Name : PCS Rx Control Block */
39/* Description : This block controls the PCS Rx Datapath mux which */
40/* provides input to the MAC over GMII. It also */
41/* controls the other GMII signals such as rx_dv and */
42/* rx_er. */
43/* */
44/* If the link is not up, as dictated by the Link */
45/* configuration state machine, the GMII interface */
46/* signals go to zero. */
47/* */
48/* End delimiters do not cause activity on the GMII. */
49/* If the T arrives on an odd the end delimiter is */
50/* RRI. If Even, the end delimiter is RI. */
51/* */
52/* Assumptions : none. */
53/* */
54/* Parent module : pcs.v */
55/* Child modules : none. */
56/* Author Name : Linda Chen */
57/* Date Created : 10/17/96 */
58/* */
59/* Copyright (c) 1994, Sun Microsystems, Inc. */
60/* Sun Proprietary and Confidential */
61/* */
62/* Modifications : */
63/* Synthesis Notes : none yet */
64/**********************************************************************/
65
66`include "pcs_define.h"
67
68module pcs_rx_ctrl (rxclk,reset_rx,enable_rx,link_up_tx, // inputs
69 kchar,rx_8bdata,kchar_p,rx_8bdata_p,kchar_pp,
70 rx_8bdata_pp,disp_err,dec_err,nxt_crs_rx,
71 got_d_linkconf_p,loss_sync_rx,odd_rx,
72
73 rx_dv,rx_er,rx_d_sel,rx_state_rx,link_up_rx, // outputs
74 nxt_crs_mask,rx_pkt_cnt_rx);
75
76input rxclk; // Rx Clk 125 MHz
77input reset_rx; // hw and sw reset OR'ed
78input enable_rx; // enable for pcs, rx clock domain
79input link_up_tx; // link up status from link config block
80input kchar; // this marks this character a K character
81// vlint flag_input_port_not_connected off
82input [7:0] rx_8bdata; // the 8 bit decoded data
83input kchar_p; // this marks the next char a K character
84input [7:0] rx_8bdata_p; // the 8 bit next decoded data
85input kchar_pp; // this marks the next next char a K character
86input [7:0] rx_8bdata_pp; // the 8 bit next next decoded data
87// vlint flag_input_port_not_connected on
88input disp_err; // marks a code which had a disparity error
89input dec_err; // marks a code which was not a valid code
90input nxt_crs_rx; // carrier sense for rx activity
91input got_d_linkconf_p; // flag for config reg data symbol
92input loss_sync_rx; // to reset rx state machine
93input odd_rx; // to check alignment of eop delims
94
95output rx_dv; // receive data valid, GMII interface
96output rx_er; // receive error, GMII interface
97output [2:0] rx_d_sel; // receive data mux select
98output [2:0] rx_state_rx; // receive control state bits for slave
99output link_up_rx; // to use by sequence detect
100output nxt_crs_mask; // to deassert crs_rx early to start IPG count
101output [10:0] rx_pkt_cnt_rx; // packet count
102
103wire end_of_pkt_rri; // marks the end of packet sequence RRI
104wire end_of_pkt_tri; // marks the end of packet sequence TRI
105wire end_of_pkt_trr; // marks the end of packet sequence TRR
106wire end_of_pkt_rs; // marks the end of packet sequence RS
107wire end_of_pkt_rrr; // marks the end delimiter error
108wire t_char; // marks the end of packet character, T
109wire h_char; // marks error being propagated
110wire r_char; // marks the carrier extension character, R
111wire r_char_p; // marks the carrier extension character, R
112wire r_char_pp; // marks the carrier extension character, R
113wire s_char_p; // marks the carrier extension character, S
114wire i_char; // marks the beginning of idle, K28.5
115wire i_char_pp; // marks the beginning of idle, K28.5
116wire beg_of_pkt; // marks the beginning of packet char, S
117wire trunc_pkt; // detection of idle or config before epd
118wire [2:0] rx_state_rx, // state of rx_ctrl state machine
119 nxt_rx_state_rx;
120wire nxt_rx_dv, // pre register MAC Control
121 nxt_rx_er; // pre register MAC Control
122wire [10:0] nxt_pkt_cnt; // next rx packet count
123wire inc_pkt_cnt; // increment packet counter
124
125// vlint flag_dangling_net_within_module off
126// vlint flag_net_has_no_load off
127// vlint flag_input_port_not_connected off
128wire [7:0] rx_8bdata; // the 8 bit decoded data
129wire [7:0] rx_8bdata_p; // the 8 bit next decoded data
130wire [7:0] rx_8bdata_pp; // the 8 bit next next decoded data
131// vlint flag_net_has_no_load on
132// vlint flag_dangling_net_within_module on
133// vlint flag_input_port_not_connected on
134
135
136
137parameter IDLE = 3'h0, // state machine states
138 RECEIVE_STREAM = 3'h1,
139 EARLY_TERM = 3'h2,
140 CARRIER_EXT = 3'h3,
141 CARRIER_EXT_ER = 3'h4,
142 FLUSH1 = 3'h5,
143 FALSE_CARRIER = 3'h6;
144
145assign
146 beg_of_pkt = kchar & rx_8bdata[`PCS_S_CHAR] & ~disp_err,
147 t_char = kchar & rx_8bdata[`PCS_T_CHAR] & ~disp_err,
148 r_char = kchar & rx_8bdata[`PCS_R_CHAR] & ~disp_err,
149 r_char_p = kchar_p & rx_8bdata_p[`PCS_R_CHAR] & ~disp_err,
150 r_char_pp = kchar_pp & rx_8bdata_pp[`PCS_R_CHAR] & ~disp_err,
151 s_char_p = kchar_p & rx_8bdata_p[`PCS_S_CHAR] & ~disp_err,
152 i_char = kchar & rx_8bdata[`PCS_K285_CHAR] & ~disp_err,
153 i_char_pp = kchar_pp & rx_8bdata_pp[`PCS_K285_CHAR] & ~disp_err,
154
155 end_of_pkt_rri = r_char & r_char_p & i_char_pp & odd_rx, // odd_rx goes with _p
156 end_of_pkt_tri = t_char & r_char_p & i_char_pp & odd_rx,
157 end_of_pkt_trr = t_char & r_char_p & r_char_pp,
158 end_of_pkt_rs = r_char & s_char_p,
159 end_of_pkt_rrr = r_char & r_char_p & r_char_pp,
160 h_char = kchar & rx_8bdata[`PCS_H_CHAR],
161 // checks for early end of packet, two idles or a config
162 trunc_pkt = (i_char & i_char_pp) | (i_char & got_d_linkconf_p),
163 nxt_pkt_cnt = (inc_pkt_cnt) ? rx_pkt_cnt_rx + 1'h1 : rx_pkt_cnt_rx;
164
165/*
166** Call of function word synchronization
167*/
168assign {nxt_rx_dv,nxt_rx_er,rx_d_sel,nxt_crs_mask,
169 inc_pkt_cnt,nxt_rx_state_rx}
170 = rx_control_fn(reset_rx,enable_rx,end_of_pkt_rri,
171 end_of_pkt_tri,end_of_pkt_trr,
172 end_of_pkt_rs,end_of_pkt_rrr,
173 nxt_crs_rx,beg_of_pkt,disp_err,h_char,
174 dec_err,link_up_rx,trunc_pkt,r_char,loss_sync_rx,
175 i_char,rx_state_rx);
176
177/*
178** Rx control state machine
179*/
180function [9:0] rx_control_fn;
181 input reset;
182 input enable;
183 input end_of_pkt_rri; // flag for end of packet sequence
184 input end_of_pkt_tri; // flag for end of packet sequence
185 input end_of_pkt_trr; // flag for end of packet sequence
186 input end_of_pkt_rs; // flag for end of packet sequence, pkt burst
187 input end_of_pkt_rrr; // marks error in the end delimiter
188 input crs_rx; // carrier sense at end of pipeline
189 input beg_of_pkt; // flag for s code detect (start of frame)
190 input disp_err; // disparity error at end of pipeline
191 input dec_err; // decode error
192 input h_char; // propogated error
193 input link_up_rx; // to deactivate GMII during link down
194 input trunc_pkt; // detection of idle or config before epd
195 input r_char; // detection of errors during carrier ext
196 input loss_sync; // to keep state machine in reset
197 input i_char; // to know when to leave false carrier state
198 input [2:0] state;
199
200 reg rx_dv; // receive data valid
201 reg rx_er; // receive error
202 reg [2:0] rx_d_sel; // mux select for rx data
203 reg crs_mask; // to make crs_rx go down early
204 reg inc_pkt_cnt; // increment pkt counter
205 reg [2:0] n_state; // next state
206
207 begin
208 rx_dv = 1'h0;
209 rx_er = 1'h0;
210 rx_d_sel = `PCS_RXD_ZERO;
211 crs_mask = 1'h0;
212 inc_pkt_cnt = 1'h0;
213 n_state = 3'h0;
214
215 case (state) // synopsys parallel_case full_case
216 IDLE : // 0
217 if (reset || ~enable)
218 n_state = IDLE;
219 else if (crs_rx & link_up_rx & ~loss_sync)
220 if (beg_of_pkt) // checks that S comes on even byte through crs_rx
221 begin
222 n_state = RECEIVE_STREAM;
223 rx_dv = 1'h1;
224 rx_d_sel = `PCS_RXD_PREAMBLE;
225 inc_pkt_cnt = 1'h1;
226 end
227 else
228 begin
229 rx_er = 1'h1;
230 n_state = FALSE_CARRIER;
231 rx_d_sel = `PCS_RXD_FALSE_CARRIER;
232 end
233 else
234 n_state = IDLE;
235 RECEIVE_STREAM : // 1
236 if (end_of_pkt_trr)
237 begin
238 n_state = CARRIER_EXT;
239 rx_er = 1'h1;
240 rx_d_sel = `PCS_RXD_CRS_EXT;
241 end
242 else if (end_of_pkt_tri)
243 begin
244 n_state = FLUSH1;
245 crs_mask = 1'h1;
246 end
247 else if (end_of_pkt_rrr)
248 begin
249 n_state = CARRIER_EXT_ER;
250 rx_er = 1'h1;
251 rx_dv = 1'h1;
252 rx_d_sel = `PCS_RXD_DECODER;
253 end
254 else if (trunc_pkt) // got K28.5
255 begin
256 n_state = EARLY_TERM;
257 rx_er = 1'h1;
258 rx_dv = 1'h1;
259 rx_d_sel = `PCS_RXD_DECODER;
260 end
261 else if (dec_err | disp_err | h_char) // bad data
262 begin
263 n_state = RECEIVE_STREAM;
264 rx_er = 1'h1;
265 rx_dv = 1'h1;
266 rx_d_sel = `PCS_RXD_DECODER;
267 end
268 else // good data
269 begin
270 rx_d_sel = `PCS_RXD_DECODER;
271 rx_dv = 1'h1;
272 n_state = RECEIVE_STREAM;
273 end
274 EARLY_TERM : // 2
275 if (crs_rx)
276 begin
277 n_state = EARLY_TERM;
278 rx_er = 1'h1;
279 rx_dv = 1'h1;
280 rx_d_sel = `PCS_RXD_DECODER;
281 end
282 else
283 n_state = IDLE;
284 CARRIER_EXT : // 3
285 if (end_of_pkt_rri) // end of pkt delim to be stripped
286 begin
287 n_state = FLUSH1;
288 crs_mask = 1'h1;
289 end
290 else if (end_of_pkt_rs) // packet bursting
291 begin
292 n_state = IDLE;
293 rx_er = 1'h1;
294 rx_d_sel = `PCS_RXD_CRS_EXT;
295 end
296 else if (!r_char | disp_err) // illegal character
297 begin
298 rx_er = 1'h1;
299 rx_d_sel = `PCS_RXD_CRS_EXT_ER;
300 n_state = CARRIER_EXT_ER;
301 end
302 else // continue carrier ext
303 begin
304 rx_er = 1'h1;
305 rx_d_sel = `PCS_RXD_CRS_EXT;
306 n_state = CARRIER_EXT;
307 end
308 CARRIER_EXT_ER : // 4
309 if (~crs_rx) // got Idle
310 n_state = IDLE;
311 else if (beg_of_pkt) // next burst
312 begin
313 n_state = RECEIVE_STREAM;
314 rx_dv = 1'h1;
315 rx_d_sel = `PCS_RXD_PREAMBLE;
316 end
317 else if (!r_char | disp_err) // illegal character
318 begin
319 rx_er = 1'h1;
320 rx_d_sel = `PCS_RXD_CRS_EXT_ER;
321 n_state = CARRIER_EXT_ER;
322 end
323 else // continue carrier ext
324 begin
325 rx_er = 1'h1;
326 rx_d_sel = `PCS_RXD_CRS_EXT;
327 n_state = CARRIER_EXT_ER;
328 end
329 FLUSH1 : // 5
330 begin
331 n_state = IDLE;
332 crs_mask = 1'h1;
333 end
334 FALSE_CARRIER : // 6
335 begin
336 rx_er = 1'h1;
337 rx_d_sel = `PCS_RXD_FALSE_CARRIER;
338 if (i_char)
339 n_state = IDLE;
340 else
341 n_state = FALSE_CARRIER;
342 end
343 default: n_state = IDLE;
344 endcase
345
346 rx_control_fn = {rx_dv,rx_er,rx_d_sel,crs_mask,inc_pkt_cnt,n_state};
347
348 end
349endfunction
350
351RREG #(3) r_state (rx_state_rx, rxclk, reset_rx | ~link_up_rx | loss_sync_rx,
352 nxt_rx_state_rx);
353SYNCREG r_link_up_tx (link_up_rx, rxclk, link_up_tx);
354RREG #(1) r_rx_dv (rx_dv, rxclk, reset_rx, nxt_rx_dv);
355RREG #(1) r_rx_er (rx_er, rxclk, reset_rx, nxt_rx_er);
356RREG #(11) r_rx_pkt_cnt (rx_pkt_cnt_rx, rxclk, reset_rx, nxt_pkt_cnt);
357
358endmodule
359
360