Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: niu_smx_resp_sio.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 | module niu_smx_resp_sio( | |
37 | /*AUTOARG*/ | |
38 | // Outputs | |
39 | resp_cmdff_wr, resp_cmdff_wdata, resp_dataff_wr, | |
40 | resp_dataff_wdata, niu_ncu_ctag_ue, niu_ncu_ctag_ce, niu_ncu_d_pe, | |
41 | // Inputs | |
42 | clk, reset_l, sio_niu_hdr_vld, sio_niu_datareq, sio_niu_data, | |
43 | sio_niu_parity, resp_cmdff_full, resp_dataff_full, | |
44 | ncu_niu_ctag_uei, ncu_niu_ctag_cei, ncu_niu_d_pei, reg_ras_cfg | |
45 | ); | |
46 | ||
47 | input clk; | |
48 | input reset_l; | |
49 | ||
50 | // sio if | |
51 | input sio_niu_hdr_vld; | |
52 | input sio_niu_datareq; | |
53 | input [127:0] sio_niu_data; | |
54 | input [7:0] sio_niu_parity; | |
55 | ||
56 | // output niu_sio_dq; // this one comes from niu_smx_resp_dmc | |
57 | ||
58 | // resp_cmdff if | |
59 | output resp_cmdff_wr; | |
60 | output [21:0] resp_cmdff_wdata; | |
61 | input resp_cmdff_full; // not use?? | |
62 | ||
63 | // resp_dataff if | |
64 | output resp_dataff_wr; | |
65 | output [143:0] resp_dataff_wdata; | |
66 | input resp_dataff_full; // not use?? | |
67 | ||
68 | // ncu ras if | |
69 | input ncu_niu_ctag_uei; | |
70 | input ncu_niu_ctag_cei; | |
71 | input ncu_niu_d_pei; | |
72 | ||
73 | output niu_ncu_ctag_ue; | |
74 | output niu_ncu_ctag_ce; | |
75 | output niu_ncu_d_pe; | |
76 | ||
77 | // pio if | |
78 | input [1:0] reg_ras_cfg; // [0] - disable(0)/enable(1) ras detect | |
79 | // [1] - disable(0)/enable(1) ras inject | |
80 | ||
81 | ||
82 | // xtb if -> this one in niu_smx_resp_dmc? | |
83 | ||
84 | // just read and put in ff | |
85 | ||
86 | // register in | |
87 | reg [127:0] sio_niu_data_r1; | |
88 | reg [7:0] sio_niu_parity_r1; | |
89 | reg [127:0] sio_niu_data_r2; | |
90 | reg [7:0] sio_niu_parity_r2; | |
91 | reg [127:0] sio_niu_data_r; | |
92 | reg [7:0] sio_niu_parity_r; | |
93 | reg sio_niu_hdr_vld_r1; | |
94 | reg sio_niu_datareq_r1; | |
95 | reg sio_niu_hdr_vld_r2; | |
96 | reg sio_niu_datareq_r2; | |
97 | reg sio_niu_hdr_vld_r; | |
98 | reg sio_niu_datareq_r; | |
99 | reg ncu_niu_ctag_uei_r; | |
100 | reg ncu_niu_ctag_cei_r; | |
101 | // reg ncu_niu_d_pei_r; | |
102 | ||
103 | reg [3:0] datawr_shift_r2; // one cycle after hdr | |
104 | reg [3:0] datawr_shift; // one cycle after hdr | |
105 | ||
106 | reg [127:0] hdr_data_r; | |
107 | reg hdr_datareq_r; | |
108 | reg hdr_err_r; | |
109 | ||
110 | reg niu_ncu_data_parity; | |
111 | reg niu_ncu_ctag_ue; | |
112 | reg niu_ncu_ctag_ce; | |
113 | ||
114 | wire niu_ncu_d_pe= niu_ncu_data_parity; | |
115 | ||
116 | wire err_inject_enable= reg_ras_cfg[1]; | |
117 | ||
118 | wire [15:0] tid_r1= sio_niu_data_r1[`SMX_SICMD_POS_ID]; | |
119 | wire tid_r1_0= (err_inject_enable & (ncu_niu_ctag_cei_r | ncu_niu_ctag_uei_r))? | |
120 | ~tid_r1[0] : tid_r1[0]; | |
121 | wire tid_r1_1= (err_inject_enable & ncu_niu_ctag_uei_r)? ~tid_r1[1] : tid_r1[1]; | |
122 | wire [5:0] tidecc_checkbit= sio_niu_data_r1[`SMX_SICMD_POS_ID_ECC]; | |
123 | wire [5:0] genpar_checkbit; | |
124 | wire genpar_cor_p5; | |
125 | ||
126 | niu_smx_ecc16_genpar ecc_genpar( | |
127 | .data ({tid_r1[15:2],tid_r1_1, tid_r1_0}), | |
128 | .chkbit (tidecc_checkbit[4:0]), | |
129 | .parity (genpar_checkbit[5:0]), | |
130 | .cor_parity_5 (genpar_cor_p5) | |
131 | ); | |
132 | ||
133 | reg [5:0] tidecc_syn_r2; | |
134 | ||
135 | // cc 061405 flipped order of bits | |
136 | wire [5:0] tidecc_syn_n= { // e=p^c in ras | |
137 | genpar_cor_p5 ^ tidecc_checkbit[5], | |
138 | genpar_checkbit[4] ^ tidecc_checkbit[4], | |
139 | genpar_checkbit[3] ^ tidecc_checkbit[3], | |
140 | genpar_checkbit[2] ^ tidecc_checkbit[2], | |
141 | genpar_checkbit[1] ^ tidecc_checkbit[1], | |
142 | genpar_checkbit[0] ^ tidecc_checkbit[0] | |
143 | }; | |
144 | ||
145 | reg [15:0] ecc_corr_tid_r; | |
146 | // reg ecc_ok_r; | |
147 | // reg ecc_corr_r; | |
148 | reg ecc_uncorr_r; | |
149 | wire [15:0] ecc_corr_tid_n; | |
150 | wire ecc_ok_n; | |
151 | wire ecc_corr_n; | |
152 | wire ecc_uncorr_n; | |
153 | ||
154 | wire [15:0] tid_r2= sio_niu_data_r2[`SMX_SICMD_POS_ID]; | |
155 | wire tid_r2_0= (err_inject_enable & (ncu_niu_ctag_cei_r | ncu_niu_ctag_uei_r))? | |
156 | ~tid_r2[0] : tid_r2[0]; | |
157 | wire tid_r2_1= (err_inject_enable & ncu_niu_ctag_uei_r)? ~tid_r2[1] : tid_r2[1]; | |
158 | ||
159 | wire err_detect_enable= reg_ras_cfg[0]; | |
160 | ||
161 | niu_smx_ecc16_corr ecc_corr( | |
162 | .enable (err_detect_enable), | |
163 | .data ({tid_r2[15:2],tid_r2_1, tid_r2_0}), | |
164 | .syn (tidecc_syn_r2[5:0]), | |
165 | .corr_data (ecc_corr_tid_n[15:0]), | |
166 | .good (ecc_ok_n), | |
167 | .corr_error (ecc_corr_n), | |
168 | .uncorr_error (ecc_uncorr_n) | |
169 | ); | |
170 | ||
171 | wire [7:0] sio_niu_parity_n; // parity to go into dataff | |
172 | ||
173 | // parity of incoming data for cmp purpose | |
174 | reg [7:0] gen_data_parity_r2; | |
175 | wire [7:0] gen_data_parity_n; | |
176 | ||
177 | wire data_r1_0= (err_inject_enable & ncu_niu_d_pei)? ~sio_niu_data_r1[0] : sio_niu_data_r1[0]; | |
178 | niu_smx_gen_siudp gen_siudp( // gen parity per N2 ras | |
179 | .data ({sio_niu_data_r1 [127:1], data_r1_0}), | |
180 | .parity (gen_data_parity_n [7:0]) | |
181 | ); | |
182 | ||
183 | wire data_parity_err_n= |(sio_niu_parity_r2^gen_data_parity_r2); | |
184 | reg dp_err_r; | |
185 | wire dp_err_n= dp_err_r | (data_parity_err_n & | |
186 | (|datawr_shift_r2)); // sample at data wr cycle | |
187 | ||
188 | always @(posedge clk) begin | |
189 | if(!reset_l) begin | |
190 | dp_err_r<= `SMX_PD 1'b0; | |
191 | niu_ncu_data_parity<= `SMX_PD 1'b0; | |
192 | end | |
193 | else begin | |
194 | if(sio_niu_hdr_vld_r2) // reset at hdr | |
195 | dp_err_r<= `SMX_PD 1'b0; | |
196 | else | |
197 | dp_err_r<= `SMX_PD dp_err_n; | |
198 | // strobe | |
199 | if(datawr_shift_r2 == 4'b0001) | |
200 | niu_ncu_data_parity<= `SMX_PD dp_err_n; | |
201 | else | |
202 | niu_ncu_data_parity<= `SMX_PD 1'b0; | |
203 | end | |
204 | end | |
205 | ||
206 | always @(posedge clk) begin | |
207 | if(!reset_l) | |
208 | datawr_shift_r2<= `SMX_PD 4'h0; | |
209 | else begin | |
210 | if(sio_niu_datareq_r2 & sio_niu_hdr_vld_r2) // qualify with hdrvld | |
211 | datawr_shift_r2<= `SMX_PD 4'hf; // ld 4cy write | |
212 | else | |
213 | datawr_shift_r2<= `SMX_PD (datawr_shift_r2>>1); | |
214 | end | |
215 | end | |
216 | ||
217 | ||
218 | always @(posedge clk) begin | |
219 | sio_niu_data_r1<= `SMX_PD sio_niu_data; | |
220 | sio_niu_parity_r1<= `SMX_PD sio_niu_parity; | |
221 | // gen ecc check bits | |
222 | ||
223 | sio_niu_data_r2<= `SMX_PD sio_niu_data_r1; | |
224 | sio_niu_parity_r2<= `SMX_PD sio_niu_parity_r1; | |
225 | gen_data_parity_r2<= `SMX_PD gen_data_parity_n; | |
226 | tidecc_syn_r2<= `SMX_PD tidecc_syn_n; | |
227 | // calc syndrome | |
228 | // syn= p^c (p=regen, c=siu's) | |
229 | ||
230 | sio_niu_data_r<= `SMX_PD sio_niu_data_r2; | |
231 | sio_niu_parity_r<= `SMX_PD sio_niu_parity_n; | |
232 | // new generated parity to store in dataff | |
233 | // gen parity on lend_convered sio_niu_data_r2 | |
234 | ||
235 | // flop in hdr data | |
236 | // keep until next hdr cycle | |
237 | if(sio_niu_hdr_vld_r2) begin | |
238 | ecc_corr_tid_r<= `SMX_PD ecc_corr_tid_n; // corrected TID | |
239 | hdr_data_r<= `SMX_PD sio_niu_data_r2; | |
240 | hdr_datareq_r<= `SMX_PD sio_niu_datareq_r2; | |
241 | end | |
242 | end | |
243 | ||
244 | always @(posedge clk) begin | |
245 | if(!reset_l) begin | |
246 | // ecc_ok_r<= `SMX_PD 1'b0; | |
247 | // ecc_corr_r<= `SMX_PD 1'b0; | |
248 | ecc_uncorr_r<= `SMX_PD 1'b0; | |
249 | hdr_err_r<= 1'b0; | |
250 | niu_ncu_ctag_ue<= `SMX_PD 1'b0; | |
251 | niu_ncu_ctag_ce<= `SMX_PD 1'b0; | |
252 | end | |
253 | else begin | |
254 | // TID ecc status, siu_hdr_ueORde flop in | |
255 | // remain until next hdr cycle | |
256 | if(sio_niu_hdr_vld_r2) begin | |
257 | // ecc_ok_r<= `SMX_PD ecc_ok_n; | |
258 | // ecc_corr_r<= `SMX_PD ecc_corr_n; | |
259 | ||
260 | ecc_uncorr_r<= `SMX_PD ecc_uncorr_n; | |
261 | hdr_err_r<= `SMX_PD |sio_niu_data_r2[`SMX_SICMD_POS_HERR]; | |
262 | end | |
263 | // strobe | |
264 | if(sio_niu_hdr_vld_r2) begin | |
265 | niu_ncu_ctag_ue<= `SMX_PD ecc_uncorr_n & !(sio_niu_data_r2[81] | sio_niu_data_r2[80]); // cc 052005 ecc_corr_n; | |
266 | // cc 061305 no ecc_uncorr if SIO already reporting | |
267 | niu_ncu_ctag_ce<= `SMX_PD ecc_corr_n; // cc 052005 ecc_uncorr_n; | |
268 | end | |
269 | else begin | |
270 | niu_ncu_ctag_ue<= `SMX_PD 1'b0; | |
271 | niu_ncu_ctag_ce<= `SMX_PD 1'b0; | |
272 | end | |
273 | end | |
274 | end | |
275 | ||
276 | always @(posedge clk) begin | |
277 | if(!reset_l) begin | |
278 | sio_niu_hdr_vld_r1<= `SMX_PD 1'b0; | |
279 | sio_niu_datareq_r1<= `SMX_PD 1'b0; | |
280 | sio_niu_hdr_vld_r2<= `SMX_PD 1'b0; | |
281 | sio_niu_datareq_r2<= `SMX_PD 1'b0; | |
282 | sio_niu_hdr_vld_r<= `SMX_PD 1'b0; | |
283 | sio_niu_datareq_r<= `SMX_PD 1'b0; | |
284 | ncu_niu_ctag_uei_r<= `SMX_PD 1'b0; | |
285 | ncu_niu_ctag_cei_r<= `SMX_PD 1'b0; | |
286 | // ncu_niu_d_pei_r<= `SMX_PD 1'b0; | |
287 | end | |
288 | else begin | |
289 | sio_niu_hdr_vld_r1<= `SMX_PD sio_niu_hdr_vld; | |
290 | sio_niu_datareq_r1<= `SMX_PD sio_niu_datareq; | |
291 | sio_niu_hdr_vld_r2<= `SMX_PD sio_niu_hdr_vld_r1; | |
292 | sio_niu_datareq_r2<= `SMX_PD sio_niu_datareq_r1; | |
293 | sio_niu_hdr_vld_r<= `SMX_PD sio_niu_hdr_vld_r2; | |
294 | sio_niu_datareq_r<= `SMX_PD sio_niu_datareq_r2; | |
295 | ncu_niu_ctag_uei_r<= `SMX_PD ncu_niu_ctag_uei; | |
296 | ncu_niu_ctag_cei_r<= `SMX_PD ncu_niu_ctag_cei; | |
297 | // ncu_niu_d_pei_r<= `SMX_PD ncu_niu_d_pei; | |
298 | end | |
299 | end | |
300 | ||
301 | always @(posedge clk) begin | |
302 | if(!reset_l) | |
303 | datawr_shift<= `SMX_PD 4'h0; | |
304 | else begin | |
305 | if(sio_niu_datareq_r & sio_niu_hdr_vld_r) // qualify with hdrvld | |
306 | datawr_shift<= `SMX_PD 4'hf; // ld 4cy write | |
307 | else | |
308 | datawr_shift<= `SMX_PD (datawr_shift>>1); | |
309 | end | |
310 | end | |
311 | ||
312 | reg resp_cmdff_wr; | |
313 | wire resp_cmdff_wr_n= (sio_niu_hdr_vld_r2 & ~sio_niu_datareq_r2) | // no data cycle | |
314 | (datawr_shift_r2==4'b0001); // last data line | |
315 | ||
316 | // resp cmdff wr | |
317 | always @(posedge clk) begin | |
318 | if(!reset_l) resp_cmdff_wr<= `SMX_PD 1'b0; | |
319 | else resp_cmdff_wr<= `SMX_PD resp_cmdff_wr_n; | |
320 | end | |
321 | ||
322 | ||
323 | wire [21:0] resp_cmdff_wdata= { // hdr cycle | |
324 | hdr_datareq_r, // in case rd w/o data (err case) | |
325 | hdr_data_r[`SMX_SICMD_POS_RESP], | |
326 | hdr_data_r[`SMX_SICMD_POS_RD], | |
327 | // sio_niu_data_r[`SMX_SICMD_POS_ERR], | |
328 | 2'h0, ((ecc_uncorr_r | hdr_err_r | dp_err_r) & err_detect_enable), | |
329 | ecc_corr_tid_r | |
330 | }; | |
331 | ||
332 | ||
333 | // gen parity for dataff at r2 stage; | |
334 | // use little endian to gen sio_niu_parity_r | |
335 | ||
336 | // big endian -> little endian | |
337 | wire [127:0] lend_data_r2_n= { sio_niu_data_r2[`SMX_BE_B15], | |
338 | sio_niu_data_r2[`SMX_BE_B14], | |
339 | sio_niu_data_r2[`SMX_BE_B13], | |
340 | sio_niu_data_r2[`SMX_BE_B12], | |
341 | sio_niu_data_r2[`SMX_BE_B11], | |
342 | sio_niu_data_r2[`SMX_BE_B10], | |
343 | sio_niu_data_r2[`SMX_BE_B9], | |
344 | sio_niu_data_r2[`SMX_BE_B8], | |
345 | sio_niu_data_r2[`SMX_BE_B7], | |
346 | sio_niu_data_r2[`SMX_BE_B6], | |
347 | sio_niu_data_r2[`SMX_BE_B5], | |
348 | sio_niu_data_r2[`SMX_BE_B4], | |
349 | sio_niu_data_r2[`SMX_BE_B3], | |
350 | sio_niu_data_r2[`SMX_BE_B2], | |
351 | sio_niu_data_r2[`SMX_BE_B1], | |
352 | sio_niu_data_r2[`SMX_BE_B0] | |
353 | }; | |
354 | ||
355 | niu_smx_gen_siudp genpar( | |
356 | .data (lend_data_r2_n [127 :0]), | |
357 | .parity (sio_niu_parity_n[7:0]) | |
358 | ); | |
359 | ||
360 | ||
361 | // resp dataff wr | |
362 | wire resp_dataff_wr= datawr_shift[0]; | |
363 | ||
364 | ||
365 | // big endian -> little endian | |
366 | wire [127:0] lend_data_n= { sio_niu_data_r[`SMX_BE_B15], | |
367 | sio_niu_data_r[`SMX_BE_B14], | |
368 | sio_niu_data_r[`SMX_BE_B13], | |
369 | sio_niu_data_r[`SMX_BE_B12], | |
370 | sio_niu_data_r[`SMX_BE_B11], | |
371 | sio_niu_data_r[`SMX_BE_B10], | |
372 | sio_niu_data_r[`SMX_BE_B9], | |
373 | sio_niu_data_r[`SMX_BE_B8], | |
374 | sio_niu_data_r[`SMX_BE_B7], | |
375 | sio_niu_data_r[`SMX_BE_B6], | |
376 | sio_niu_data_r[`SMX_BE_B5], | |
377 | sio_niu_data_r[`SMX_BE_B4], | |
378 | sio_niu_data_r[`SMX_BE_B3], | |
379 | sio_niu_data_r[`SMX_BE_B2], | |
380 | sio_niu_data_r[`SMX_BE_B1], | |
381 | sio_niu_data_r[`SMX_BE_B0] | |
382 | }; | |
383 | // wire resp_dataff_err= dp_err_r; | |
384 | wire [143:0] resp_dataff_wdata= {8'h0, sio_niu_parity_r, lend_data_n}; | |
385 | ||
386 | endmodule | |
387 |