Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / pcs_decoder.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: pcs_decoder.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_decoder.v 1.3G
36/**********************************************************************/
37/* Project Name : CASSINI */
38/* Module Name : PCS Decoder Block */
39/* Description : This block decodes an incoming data stream of */
40/* 10 bits to 8 bits of data as well as special */
41/* characters. The Fibre channel special characters */
42/* are called K characters. They go along with */
43/* special data symbols to mark an "ordered set". */
44/* The K characters are flagged with kchar and the */
45/* the special data characters are flagged also. */
46/* Running disparity is calculated on a per clock */
47/* regardless of disparity errors. Running disparity */
48/* and decode errors are flagged. Kchar and special */
49/* chararacter flags are not asserted when a decode */
50/* error occurs. */
51/* */
52/* Assumptions : none. */
53/* */
54/* Parent module : pcs_rx_dpath.v */
55/* Child modules : pcs_rx_disparity.v */
56/* Author Name : Linda Chen */
57/* Date Created : 10/21/96 */
58/* */
59/* Copyright (c) 1994, Sun Microsystems, Inc. */
60/* Sun Proprietary and Confidential */
61/* */
62/* Modifications : */
63/* 7/22/97 : removed flag got_d_idle_pp, not needed */
64/* 11/14/97: removed if else check for I1 and I2 */
65/* 11/14/97: added decode check for reserved K chars */
66/* 11/14/97: marked unknown kchar as none of the known */
67/* ones */
68/* 12/9/98 : added detection for characters within 1 */
69/* bit of K28.5 of correct disparity for */
70/* carrier detect generation */
71/* Synthesis Notes : none yet */
72/**********************************************************************/
73
74module pcs_decoder(rx_10bdec_in,rxclk, // inputs
75
76 rx_8bdec_out,dec_err_pp,disp_err_pp, // outputs
77 kchar_pp,got_d_linkconf_pp,comma_pp,k285w1_pp);
78
79input [9:0] rx_10bdec_in; // receive encoded 10 bit data
80input rxclk; // rxclk, 125 MHz
81
82output [7:0] rx_8bdec_out; // decoded data byte
83output dec_err_pp, // flag to mark decoding error
84 disp_err_pp; // flag to mark running disparity error
85output kchar_pp; // flag to mark k character
86output got_d_linkconf_pp; // flag to mark special char for link conf
87output comma_pp; // flag to mark comma characters
88output k285w1_pp; // flag to mark all chars within 1 bit
89 // the same as k28.5
90
91wire dec_err1,dec_err2, // decode error flags for most/least sig bits
92 rderr1, rderr2, // running disp. flags for most/least sig bits
93 RDreg, newRD; // running disparity signals
94wire k285w1_p_match, // find characters within one bit of k28.5
95 k285w1_n_match; // of the right disparity for carrier detect
96
97wire pos_disp;
98
99/*
100** Running disparity calculator
101*/
102pcs_rx_disparity pcs_rx_disparity (rx_10bdec_in, RDreg, newRD, pos_disp);
103
104/*
105** Call of functions to decode most and least significant bits of data
106*/
107assign {rx_8bdec_out[4:0],dec_err1,kchar_pp,//got_d_idle_pp,
108 got_d_linkconf_pp,comma_pp,rderr1} =
109 deco1_fcn(rx_10bdec_in,RDreg),
110 {rx_8bdec_out[7:5],dec_err2,rderr2} =
111 deco2_fcn(rx_10bdec_in[3:0],newRD,kchar_pp);
112
113
114assign dec_err_pp = dec_err1 | dec_err2,
115 disp_err_pp = rderr1 | rderr2,
116 k285w1_p_match = ((rx_10bdec_in == 10'b110000_0101) ||
117 (rx_10bdec_in == 10'b010000_0101) ||
118 (rx_10bdec_in == 10'b100000_0101) ||
119 (rx_10bdec_in == 10'b111000_0101) ||
120 (rx_10bdec_in == 10'b110100_0101) ||
121 (rx_10bdec_in == 10'b110010_0101) ||
122 (rx_10bdec_in == 10'b110001_0101) ||
123 (rx_10bdec_in == 10'b110000_1101) ||
124 (rx_10bdec_in == 10'b110000_0001) ||
125 (rx_10bdec_in == 10'b110000_0111) ||
126 (rx_10bdec_in == 10'b110000_0100) ),
127 k285w1_n_match = ((rx_10bdec_in == 10'b001111_1010) ||
128 (rx_10bdec_in == 10'b101111_1010) ||
129 (rx_10bdec_in == 10'b011111_1010) ||
130 (rx_10bdec_in == 10'b000111_1010) ||
131 (rx_10bdec_in == 10'b001011_1010) ||
132 (rx_10bdec_in == 10'b001101_1010) ||
133 (rx_10bdec_in == 10'b001110_1010) ||
134 (rx_10bdec_in == 10'b001111_0010) ||
135 (rx_10bdec_in == 10'b001111_1110) ||
136 (rx_10bdec_in == 10'b001111_1000) ||
137 (rx_10bdec_in == 10'b001111_1011)),
138 k285w1_pp = ((k285w1_n_match & ~RDreg) || (k285w1_p_match & RDreg));
139
140
141/*
142** Register to hold running disparity
143*/
144REG #(1) r_run_disp ( .din(pos_disp), .clk(rxclk), .qout(RDreg) );
145
146/*
147** Function to do 6b5b decode on most significant bits of rx_10bdata
148** ~RDreg means that you can only get this code if the beginning
149** running disparity is one. So if zero, error is flagged.
150** RDreg means that you can only get this code if the beginning
151** running disparity is zero. So if one, error is flagged.
152** 1'b0 means that this code can be received whether the
153** running disparity is zero or one. So no check is done.
154**
155** The function output is:
156** {decodata[4:0],dec_err1,kchar,got_d_linkconf_pp,rderr}
157*/
158function [9:0] deco1_fcn;
159 input [9:0] rx_data;
160 input RDreg;
161
162 case (rx_data[9:4]) //synopsys parallel_case
163 6'b011000: deco1_fcn = {5'b00000,2'b00,1'b0,1'b0,~RDreg};
164 6'b100111: deco1_fcn = {5'b00000,2'b00,1'b0,1'b0,RDreg};
165 6'b100010: deco1_fcn = {5'b00001,2'b00,1'b0,1'b0,~RDreg};
166 6'b011101: deco1_fcn = {5'b00001,2'b00,1'b0,1'b0,RDreg};
167 /* D2 */ 6'b010010: if (rx_data[3:0]==4'b0101) // ConfigB
168 deco1_fcn = {5'b00010,2'b00,1'b1,1'b0,~RDreg};
169 else deco1_fcn = {5'b00010,2'b00,1'b0,1'b0,~RDreg};
170 /* D2 */ 6'b101101: if (rx_data[3:0]==4'b0101) // ConfigB
171 deco1_fcn = {5'b00010,2'b00,1'b1,1'b0,RDreg};
172 else deco1_fcn = {5'b00010,2'b00,1'b0,1'b0,RDreg};
173 6'b110001: deco1_fcn = {5'b00011,2'b00,1'b0,1'b0,1'b0};
174 6'b001010: deco1_fcn = {5'b00100,2'b00,1'b0,1'b0,~RDreg};
175 6'b110101: deco1_fcn = {5'b00100,2'b00,1'b0,1'b0,RDreg};
176 /* D5 */ 6'b101001: deco1_fcn = {5'b00101,2'b00,1'b0,1'b0,1'b0}; // I1
177 6'b011001: deco1_fcn = {5'b00110,2'b00,1'b0,1'b0,1'b0};
178 6'b000111: deco1_fcn = {5'b00111,2'b00,1'b0,1'b0,~RDreg};
179 6'b111000: deco1_fcn = {5'b00111,2'b00,1'b0,1'b0,RDreg};
180 6'b000110: deco1_fcn = {5'b01000,2'b00,1'b0,1'b0,~RDreg};
181 6'b111001: deco1_fcn = {5'b01000,2'b00,1'b0,1'b0,RDreg};
182 6'b100101: deco1_fcn = {5'b01001,2'b00,1'b0,1'b0,1'b0};
183 6'b010101: deco1_fcn = {5'b01010,2'b00,1'b0,1'b0,1'b0};
184 6'b110100: deco1_fcn = {5'b01011,2'b00,1'b0,1'b0,1'b0};
185 6'b001101: deco1_fcn = {5'b01100,2'b00,1'b0,1'b0,1'b0};
186 6'b101100: deco1_fcn = {5'b01101,2'b00,1'b0,1'b0,1'b0};
187 6'b011100: deco1_fcn = {5'b01110,2'b00,1'b0,1'b0,1'b0};
188 6'b101000: deco1_fcn = {5'b01111,2'b00,1'b0,1'b0,~RDreg};
189 6'b010111: deco1_fcn = {5'b01111,2'b00,1'b0,1'b0,RDreg};
190 /* D16 */ 6'b100100: deco1_fcn = {5'b10000,2'b00,1'b0,1'b0,~RDreg}; // I2
191 /* D16 */ 6'b011011: deco1_fcn = {5'b10000,2'b00,1'b0,1'b0,RDreg}; // I2
192 6'b100011: deco1_fcn = {5'b10001,2'b00,1'b0,1'b0,1'b0};
193 6'b010011: deco1_fcn = {5'b10010,2'b00,1'b0,1'b0,1'b0};
194 6'b110010: deco1_fcn = {5'b10011,2'b00,1'b0,1'b0,1'b0};
195 6'b001011: deco1_fcn = {5'b10100,2'b00,1'b0,1'b0,1'b0};
196 /* D21 */ 6'b101010: if (rx_data[3:0]==4'b1010) // ConfigA
197 deco1_fcn = {5'b10101,2'b00,1'b1,1'b0,1'b0};
198 else deco1_fcn = {5'b10101,2'b00,1'b0,1'b0,1'b0};
199 6'b011010: deco1_fcn = {5'b10110,2'b00,1'b0,1'b0,1'b0};
200 /* D23 */ 6'b000101: if (rx_data[3:0]==4'b0111) // R
201 deco1_fcn = {5'b00001,2'b01,1'b0,1'b0,~RDreg};
202 else deco1_fcn = {5'b10111,2'b00,1'b0,1'b0,~RDreg};
203 /* D23 */ 6'b111010: if (rx_data[3:0]==4'b1000) // R
204 deco1_fcn = {5'b00001,2'b01,1'b0,1'b0,RDreg};
205 else deco1_fcn = {5'b10111,2'b00,1'b0,1'b0,RDreg};
206 6'b001100: deco1_fcn = {5'b11000,2'b00,1'b0,1'b0,~RDreg};
207 6'b110011: deco1_fcn = {5'b11000,2'b00,1'b0,1'b0,RDreg};
208 6'b100110: deco1_fcn = {5'b11001,2'b00,1'b0,1'b0,1'b0};
209 6'b010110: deco1_fcn = {5'b11010,2'b00,1'b0,1'b0,1'b0};
210 /* D27 */ 6'b001001: if (rx_data[3:0]==4'b0111) // S
211 deco1_fcn = {5'b00010,2'b01,1'b0,1'b0,~RDreg};
212 else deco1_fcn = {5'b11011,2'b00,1'b0,1'b0,~RDreg};
213 /* D27 */ 6'b110110: if (rx_data[3:0]==4'b1000) // S
214 deco1_fcn = {5'b00010,2'b01,1'b0,1'b0,RDreg};
215 else deco1_fcn = {5'b11011,2'b00,1'b0,1'b0,RDreg};
216 6'b001110: deco1_fcn = {5'b11100,2'b00,1'b0,1'b0,1'b0};
217 /* D29 */ 6'b010001: if (rx_data[3:0]==4'b0111) // T
218 deco1_fcn = {5'b00100,2'b01,1'b0,1'b0,~RDreg};
219 else deco1_fcn = {5'b11101,2'b00,1'b0,1'b0,~RDreg};
220 /* D29 */ 6'b101110: if (rx_data[3:0]==4'b1000) // T
221 deco1_fcn = {5'b00100,2'b01,1'b0,1'b0,RDreg};
222 else deco1_fcn = {5'b11101,2'b00,1'b0,1'b0,RDreg};
223 /* D30 */ 6'b100001: if (rx_data[3:0]==4'b0111) // H
224 deco1_fcn = {5'b01000,2'b01,1'b0,1'b0,~RDreg};
225 else deco1_fcn = {5'b11110,2'b00,1'b0,1'b0,~RDreg};
226 /* D30 */ 6'b011110: if (rx_data[3:0]==4'b1000) // H
227 deco1_fcn = {5'b01000,2'b01,1'b0,1'b0,RDreg};
228 else deco1_fcn = {5'b11110,2'b00,1'b0,1'b0,RDreg};
229 6'b010100: deco1_fcn = {5'b11111,2'b00,1'b0,1'b0,~RDreg};
230 6'b101011: deco1_fcn = {5'b11111,2'b00,1'b0,1'b0,RDreg};
231 /* K28 */ 6'b001111: if (rx_data[3:0]==4'b1010)
232 deco1_fcn = {5'b10000,2'b01,1'b0,1'b1,RDreg};
233 else if (rx_data[3:0]==4'b1001)
234 deco1_fcn = {5'b00000,2'b01,1'b0,1'b1,RDreg};
235 else if (rx_data[3:0]==4'b1000)
236 deco1_fcn = {5'b00000,2'b01,1'b0,1'b1,RDreg};
237 else deco1_fcn = {5'h0,2'b01,1'b0,1'b0,RDreg};
238 /* K28 */ 6'b110000: if (rx_data[3:0]==4'b0101)
239 deco1_fcn = {5'b10000,2'b01,1'b0,1'b1,~RDreg};
240 else deco1_fcn = {5'h0,2'b01,1'b0,1'b0,RDreg};
241 default:
242 deco1_fcn = {5'h0,2'b10,1'b0,1'b0,1'b0}; // dec_err1
243 endcase
244 endfunction
245
246/*
247** Function to do 4b3b decode on least significant bits of rx_10bdata
248** This decodes and checks K characters properly also.
249*/
250function [4:0] deco2_fcn; //{decodata[7:5],dec_err2,rderr2}
251 input [3:0] rx_data;
252 input newRD, kchar;
253 if (kchar)
254 deco2_fcn = {3'b111,1'b0,(rx_data[3]^newRD)};
255 else
256 case (rx_data[3:0]) //synopsys parallel_case
257 4'b1011: deco2_fcn = {3'b000,1'b0,newRD};
258 4'b0100: deco2_fcn = {3'b000,1'b0,~newRD};
259 4'b1001: deco2_fcn = {3'b001,2'b0};
260 4'b0101: deco2_fcn = {3'b010,2'b0};
261 4'b1100: deco2_fcn = {3'b011,1'b0,newRD};
262 4'b0011: deco2_fcn = {3'b011,1'b0,~newRD};
263 4'b1101: deco2_fcn = {3'b100,1'b0,newRD};
264 4'b0010: deco2_fcn = {3'b100,1'b0,~newRD};
265 4'b1010: deco2_fcn = {3'b101,2'b0};
266 4'b0110: deco2_fcn = {3'b110,2'b0};
267 4'b1110: deco2_fcn = {3'b111,1'b0,newRD};
268 4'b0001: deco2_fcn = {3'b111,1'b0,~newRD};
269 4'b1000: deco2_fcn = {3'b111,1'b0,~newRD};
270 4'b0111: deco2_fcn = {3'b111,1'b0,newRD};
271 default : deco2_fcn[4:0] = 5'b00010;
272 endcase
273 endfunction
274
275endmodule