| 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 | |