Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_dsn_ctl.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: dmu_dsn_ctl.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 ============================================
35module dmu_dsn_ctl (
36 // clocks, scan
37 l1clk,
38 rst_l,
39 reset,
40
41 // upstream from DMU TO SIU
42 dmu_sii_hdr_vld,
43 dmu_sii_reqbypass,
44 dmu_sii_datareq,
45 dmu_sii_datareq16,
46 dmu_sii_data,
47 dmu_sii_parity,
48 dmu_sii_be_parity,
49 dmu_sii_be,
50
51 // downstream from SIU TO DMU
52 sio_dmu_hdr_vld,
53
54 sii_dmu_wrack_tag,
55 sii_dmu_wrack_par,
56 sii_dmu_wrack_vld,
57 sio_dmu_data,
58 sio_dmu_parity,
59
60
61 // ========== DMU PIO ==========
62 // downstream
63 ncu_dmu_pio_hdr_vld,
64 ncu_dmu_mmu_addr_vld,
65 ncu_dmu_pio_data,
66 ncu_dmu_d_pei, // n2 RAS
67 ncu_dmu_siicr_pei, // n2 RAS
68 ncu_dmu_ctag_uei, // n2 RAS
69 ncu_dmu_ctag_cei, // n2 RAS
70 ncu_dmu_ncucr_pei, // n2 RAS
71 ncu_dmu_iei, // n2 RAS
72 dmu_ncu_wrack_vld,
73 dmu_ncu_wrack_tag,
74 dmu_ncu_wrack_par, // n2 RAS
75 dmu_ncu_d_pe, // n2 RAS
76 dmu_ncu_siicr_pe, // n2 RAS
77 dmu_ncu_ctag_ue, // n2 RAS
78 dmu_ncu_ctag_ce, // n2 RAS
79 dmu_ncu_ncucr_pe, // n2 RAS
80 dmu_ncu_ie, // n2 RAS
81 // ========== DMU PIO ==========
82
83 // ========== DMU Mondo ==========
84 ncu_dmu_mondo_ack,
85 ncu_dmu_mondo_nack,
86 ncu_dmu_mondo_id,
87 ncu_dmu_mondo_id_par,
88 // ========== DMU Mondo ==========
89
90 // ========== DMU/DSN command port ==========
91 d2j_cmd,
92 d2j_addr,
93 d2j_ctag,
94 d2j_cmd_vld,
95 // ========== DMU/DSN command port==========
96
97 // ========== DMU/DSN data port ==========
98 d2j_data,
99 d2j_bmsk,
100 d2j_data_par,
101 d2j_data_vld,
102 // ========== DMU/DSN data port==========
103
104 // ========== CTM DMA Wrack Port ==========
105 j2d_d_wrack_tag,
106 j2d_d_wrack_vld,
107 // ========== CTM DMA Wrack Port==========
108
109 // ========== CTM PIO Wrack Port ==========
110 d2j_p_wrack_tag,
111 d2j_p_wrack_vld,
112 // ========== CTM PIO Wrack Port==========
113
114 // ========== CRM Command Completion Port ==========
115 j2d_di_cmd,
116 j2d_di_ctag,
117 j2d_di_cmd_vld,
118 // ========== CRM Command Completion Port==========
119
120 // ========== CRM Command Request Port ==========
121 j2d_p_cmd,
122 j2d_p_addr,
123 j2d_p_bmsk,
124 j2d_p_ctag,
125 j2d_p_cmd_vld,
126 // ========== CRM Command Request Port==========
127
128 // ========== CRM Data Completion Port ==========
129 j2d_d_data,
130 j2d_d_data_par,
131 j2d_d_data_err,
132 j2d_d_data_vld,
133 // ========== CRM Data Completion Port==========
134
135 // ========== CRM Data Request Port ==========
136 j2d_p_data,
137 j2d_p_data_par,
138 j2d_p_data_vld,
139 // ========== CRM Data Request Port==========
140
141 // ========== DMU MMU Invalidate Port ==========
142 j2d_mmu_addr_vld,
143 j2d_mmu_addr,
144 // ========== DMU/DSN MMU Invalidate Port==========
145
146 // ========== DSN/MMU force parity error ==========
147 dsn_dmc_iei,
148 // ========== DSN/MMU force parity error ==========
149
150 // ========== DSN CRU debug bus==========
151 cr2ds_dbg_sel_a,
152 cr2ds_dbg_sel_b,
153 ds2cr_dbg_a,
154 ds2cr_dbg_b,
155 ucb2ctl_dbg_grp_a_1,
156 fsm2ctl_dbg_grp_b_1,
157 pkt2ctl_dbg_grp_b_1,
158 // ========== DSN CRU debug bus==========
159
160 // ========== DSN dbg stall ==========
161 dbg1_dmu_stall,
162 dbg1_dmu_resume,
163 dmu_dbg1_stall_ack,
164 ds2cl_stall
165 // ========== DSN dbg stall ==========
166);
167
168
169
170 // clocks, scan
171 input l1clk; // io clock
172 input rst_l; //
173 output reset; //
174
175
176 // upstream from DMU TO SIU
177 output dmu_sii_hdr_vld; // DMU requesting to send packet to SIU
178 output dmu_sii_reqbypass; // DMU requesting to send packet to bypass queue of SIU
179 output dmu_sii_datareq; // DMU requesting to send packet w/data to SIU
180 output dmu_sii_datareq16; // DMU requesting to send packet w/16B only
181 output [127:0] dmu_sii_data; // Packet from DMU to SIU
182 output [7:0] dmu_sii_parity; // Packet parity from DMU to SIU
183 output dmu_sii_be_parity; // byte enable parity from DMU to SIU
184 output [15:0] dmu_sii_be; // Packet byte enables from DMU to SIU
185
186 // downstream from SIU TO DMU
187 input sio_dmu_hdr_vld; // SIU requesting to send DMA rd cpl to DMU
188 input [3:0] sii_dmu_wrack_tag; // credit value returned to DMU for all DMA writes/int.
189 input sii_dmu_wrack_par; // n2 RAS, odd parity on sii_dmu_wrack_tag, drop j2d_d_wrack_vld if error
190 input sii_dmu_wrack_vld; // asserted by SII to indicate a DMA write credit is returned
191 input [127:0] sio_dmu_data; // Packet from SIU to DMU
192 input [7:0] sio_dmu_parity; // Packet parity from SIU to DMU
193
194
195
196 // ========== DMU PIO ==========
197 // downstream
198 input ncu_dmu_pio_hdr_vld; // NCU to DSN pio_data header is valid
199 input ncu_dmu_mmu_addr_vld; // NCU to DMU pio_data mmu invalidate vector is valid
200 input [63:0] ncu_dmu_pio_data; // NCU to DMU pio_data bus.
201 input ncu_dmu_d_pei; // n2 RAS
202 input ncu_dmu_siicr_pei; // n2 RAS
203 input ncu_dmu_ctag_uei; // n2 RAS
204 input ncu_dmu_ctag_cei; // n2 RAS
205 input ncu_dmu_ncucr_pei; // n2 RAS
206 input ncu_dmu_iei; // n2 RAS
207 output dmu_ncu_wrack_vld; // DMU to NCU release credit is valid
208 output [3:0] dmu_ncu_wrack_tag; // DMU to NCU release credit value
209 output dmu_ncu_wrack_par; // DMU to NCU parity on dmu_ncu_wrack_tag
210 output dmu_ncu_d_pe; // n2 RAS
211 output dmu_ncu_siicr_pe; // n2 RAS
212 output dmu_ncu_ctag_ue; // n2 RAS
213 output dmu_ncu_ctag_ce; // n2 RAS
214 output dmu_ncu_ncucr_pe; // n2 RAS
215 output dmu_ncu_ie; // n2 RAS
216 // ========== DMU PIO ==========
217
218 // ========== DMU Mondo ==========
219 input ncu_dmu_mondo_ack; // Mondo Interrupt ack
220 input ncu_dmu_mondo_nack; // Mondo Interrupt nack
221 input [5:0] ncu_dmu_mondo_id; // Mondo Interrupt ID
222 input ncu_dmu_mondo_id_par; // Mondo Interrupt ID par(odd), if error drop j2d_di_cmd_vld packet to dmc
223 // ========== DMU Mondo ==========
224
225 // ========== DMU/DSN command port ==========
226 input [3:0] d2j_cmd; //
227 input [36:0] d2j_addr; //
228 input [15:0] d2j_ctag; //
229 input d2j_cmd_vld; //
230 // ========== DMU/DSN command port==========
231
232 // ========== DMU/DSN data port ==========
233 input [127:0] d2j_data; //
234 input [15:0] d2j_bmsk; //
235 input [4:0] d2j_data_par; //
236 input d2j_data_vld; //
237 // ========== DMU/DSN data port==========
238
239 // ========== CTM DMA Wrack Port ==========
240 output [3:0] j2d_d_wrack_tag; //
241 output j2d_d_wrack_vld; //
242 // ========== CTM DMA Wrack Port==========
243
244 // ========== CTM PIO Wrack Port ==========
245 input [3:0] d2j_p_wrack_tag; //
246 input d2j_p_wrack_vld; //
247 // ========== CTM PIO Wrack Port==========
248
249 // ========== CRM Command Completion Port ==========
250 output [1:0] j2d_di_cmd; //
251 output [15:0] j2d_di_ctag; //
252 output j2d_di_cmd_vld; //
253 // ========== CRM Command Completion Port==========
254
255 // ========== CRM Command Request Port ==========
256 output [3:0] j2d_p_cmd; //
257 output [35:0] j2d_p_addr; //
258 output [15:0] j2d_p_bmsk; //
259 output [10:0] j2d_p_ctag; //
260 output j2d_p_cmd_vld; //
261 // ========== CRM Command Request Port==========
262
263 // ========== CRM Data Completion Port ==========
264 output [127:0] j2d_d_data; //
265 output [3:0] j2d_d_data_par; //
266 output j2d_d_data_err; //
267 output j2d_d_data_vld; //
268 // ========== CRM Data Completion Port==========
269
270 // ========== CRM Data Request Port ==========
271 output [127:0] j2d_p_data; //
272 output [3:0] j2d_p_data_par; //
273 output j2d_p_data_vld; //
274 // ========== CRM Data Request Port==========
275
276 // ========== DMU/DSN MMU Invalidate Port ==========
277 output j2d_mmu_addr_vld; //
278 output [42:6] j2d_mmu_addr; //
279 // ========== DMU/DSN MMU Invalidate Port==========
280
281 // ========== DSN/MMU force parity error ==========
282 output dsn_dmc_iei;
283 // ========== DSN/MMU force parity error ==========
284
285 // ========== DSN CRU debug bus==========
286 input [`FIRE_DLC_DEBUG_SEL_WDTH-1:0] cr2ds_dbg_sel_a;
287 input [`FIRE_DLC_DEBUG_SEL_WDTH-1:0] cr2ds_dbg_sel_b;
288 output [`FIRE_DEBUG_WDTH-1:0] ds2cr_dbg_a;
289 output [`FIRE_DEBUG_WDTH-1:0] ds2cr_dbg_b;
290 input [`FIRE_DEBUG_WDTH-1:0] ucb2ctl_dbg_grp_a_1;
291 input [4:0] fsm2ctl_dbg_grp_b_1;
292 input [2:0] pkt2ctl_dbg_grp_b_1;
293 // ========== DSN CRU debug bus==========
294
295 // ========== DSN dbg stall ==========
296 input dbg1_dmu_stall;
297 input dbg1_dmu_resume;
298 output dmu_dbg1_stall_ack;
299 output ds2cl_stall;
300 // ========== DSN dbg stall ==========
301
302
303assign reset = ~rst_l;
304
305
306// ----------------------------------------------------------------------------
307// Variables
308// ----------------------------------------------------------------------------
309 reg [127:0] d2j_data_d1;
310 reg [42:0] pio_pa;
311 reg [15:0] dmu_sii_be,sio_dmc_tag;
312 reg dmu_sii_parity_be;
313 wire [7:0] dmu_sii_parity;
314 reg [3:0] pio_credit_id;
315 reg [7:0] pio_byte_cnt;
316 reg [5:0] sio_dmc_tag_ecc;
317 reg sio_dmu_hdr_vld_d1,pio_read,mmu_addr_vld,j2d_p_cmd_vld;
318 reg dsn_sii_cmd_7,sio_dmu_ue,sio_dmu_de;
319 reg [2:0] hdr_cnt,nxt_hdr_cnt;
320 reg [1:0] pio_cmd_map;
321 reg [6:0] pio_id;
322 reg [7:0] pio_rd_bmsk;
323 reg [15:0] pio_bmsk;
324 reg [11:8] d2j_ctag_d1;
325 reg ncu_dmu_d_pei_d1,ncu_dmu_siicr_pei_d1,ncu_dmu_ctag_uei_d1;
326 reg ncu_dmu_ctag_cei_d1,ncu_dmu_ncucr_pei_d1,ncu_dmu_iei_d1;
327 reg force_dmu_sii_bad_par_d1;
328 wire force_dmu_sii_bad_par;
329 wire dmu_ncu_d_pe_in,dmu_ncu_siicr_pe_in,dmu_ncu_ctag_ue_in;
330 wire dmu_ncu_ctag_ce_in,dmu_ncu_ncucr_pe_in,dmu_ncu_ie_in;
331 reg dmu_ncu_d_pe,dmu_ncu_siicr_pe,dmu_ncu_ctag_ue;
332 reg dmu_ncu_ctag_ce,dmu_ncu_ncucr_pe,dmu_ncu_ie;
333 wire [7:0] calc_sio_dmu_data_par;
334 wire [4:0] calc_d2j_data_par;
335 wire [127:0] dsn_sii_hdr,d2j_pio_data,d2j_data_out;
336 wire [7:0] dsn_sii_cmd,data_in,data_out;
337 wire dsn_sii_to,dsn_sii_be,dsn_sii_ue,read,write,fifo_empty,mondo_cmd_vld;
338 wire [1:0] adr_par;
339 wire cmd_par,sio_dsn_pe;
340 wire [1:0] pio_cpl_bus_align;
341 wire [15:0] ctag_to_siu;
342 wire [5:0] hdr_ecc;
343 wire [17:0] sio_dsn_hdr_ecc;
344 wire [15:0] sio_dmc_tag_corrected;
345 wire [2:0] pio_bmsk_sel;
346 reg [3:0] enable_pe_err;
347
348 reg [`FIRE_DEBUG_WDTH-1:0] n_dsn_dbg_a;
349 reg [`FIRE_DEBUG_WDTH-1:0] n_dsn_dbg_b;
350 reg [`FIRE_DEBUG_WDTH-1:0] ds2cr_dbg_a;
351 reg [`FIRE_DEBUG_WDTH-1:0] ds2cr_dbg_b;
352 wire [`FIRE_DEBUG_WDTH-1:0] n_dbg_grp_a_2,n_dbg_grp_a_3 ;
353 wire [`FIRE_DEBUG_WDTH-1:0] n_dbg_grp_b_2 ;
354
355
356// ----------------------------------------------------------------------------
357// Zero In Checkers
358// ----------------------------------------------------------------------------
359// checker to verify on pio rd cpl's that bmsk is only valid on one of the 64 bits
360/* ////0in assert -var (((d2j_bmsk[15:0] & `MASK1) == 16'h0000)
361 || ((d2j_bmsk[15:0] & `MASK2) == 16'h0000))
362 -active (d2j_data_vld & d2j_cmd[3])
363 -module dmu_dsn_ctl
364 -name pio_rd_cpl_bmsk
365*/
366//BP n2 10-06-04 checker to make sure that DMC does not send back to back
367// data transactions, because the DSN inserts a header thus it needs 1
368// extra cycle
369// first for all dma writes, which are 4 data beats
370/* 0in assert_follower -leader (d2j_cmd_vld & d2j_data_vld & ((d2j_cmd[3:0] == 4'b0000) ||
371 (d2j_cmd[3:0] == 4'b0001)) )
372 -follower ( ~d2j_cmd_vld )
373 -max 4
374 -min 1
375*/
376// second for pio 16 byte read return, interrupts, pio rd return errors
377/* 0in assert_follower -leader (d2j_cmd_vld & d2j_data_vld & ((d2j_cmd[3:0] == 4'b0100) ||
378 (d2j_cmd[3:0] == 4'b1000) ))
379 -follower ( ~d2j_cmd_vld )
380 -max 1
381 -min 1
382*/
383// ----------------------------------------------------------------------------
384// flops used in DMU/DSN xface
385// ----------------------------------------------------------------------------
386always @(posedge l1clk )
387 if (~rst_l) begin
388 d2j_data_d1[127:0] <= 128'b0;
389 dmu_sii_be[15:0] <= 16'b0;
390 dmu_sii_parity_be <= 1'b0;
391 dsn_sii_cmd_7 <= 1'b0;
392 d2j_ctag_d1[11:8] <= 4'b0;
393 ncu_dmu_d_pei_d1 <= 1'b0;
394 ncu_dmu_siicr_pei_d1 <= 1'b0;
395 ncu_dmu_ctag_uei_d1 <= 1'b0;
396 ncu_dmu_ctag_cei_d1 <= 1'b0;
397 ncu_dmu_ncucr_pei_d1 <= 1'b0;
398 ncu_dmu_iei_d1 <= 1'b0;
399 dmu_ncu_d_pe <= 1'b0;
400 dmu_ncu_siicr_pe <= 1'b0;
401 dmu_ncu_ctag_ue <= 1'b0;
402 dmu_ncu_ctag_ce <= 1'b0;
403 dmu_ncu_ncucr_pe <= 1'b0;
404 dmu_ncu_ie <= 1'b0;
405 force_dmu_sii_bad_par_d1 <= 1'b0;
406 end
407 else begin
408 if (d2j_data_vld || // for normal dma writes
409 (d2j_cmd_vld && d2j_cmd[3] && ~d2j_cmd[2] && d2j_cmd[1]) ) // if cpl err( TO or BERR)
410 d2j_data_d1[127:0] <= d2j_data[127:0];
411 if (d2j_data_vld ) dmu_sii_be[15:0] <= d2j_bmsk[15:0];
412 if (d2j_data_vld ) dmu_sii_parity_be <= d2j_data_par[0];
413 if (d2j_cmd_vld ) dsn_sii_cmd_7 <= d2j_cmd[3];
414 if (d2j_cmd_vld ) d2j_ctag_d1[11:8] <= d2j_ctag[11:8];
415 ncu_dmu_d_pei_d1 <= ncu_dmu_d_pei;
416 ncu_dmu_siicr_pei_d1 <= ncu_dmu_siicr_pei;
417 if(sio_dmu_hdr_vld) ncu_dmu_ctag_uei_d1 <= ncu_dmu_ctag_uei;
418 ncu_dmu_ctag_cei_d1 <= ncu_dmu_ctag_cei;
419 ncu_dmu_ncucr_pei_d1 <= ncu_dmu_ncucr_pei;
420 ncu_dmu_iei_d1 <= ncu_dmu_iei;
421 dmu_ncu_d_pe <= dmu_ncu_d_pe_in;
422 dmu_ncu_siicr_pe <= dmu_ncu_siicr_pe_in;
423 dmu_ncu_ctag_ue <= dmu_ncu_ctag_ue_in;
424 dmu_ncu_ctag_ce <= dmu_ncu_ctag_ce_in;
425 dmu_ncu_ncucr_pe <= dmu_ncu_ncucr_pe_in;
426 dmu_ncu_ie <= dmu_ncu_ie_in;
427 force_dmu_sii_bad_par_d1 <= force_dmu_sii_bad_par;
428 end
429
430assign dmu_ncu_ie_in = 1'b0;
431assign dsn_dmc_iei = ncu_dmu_iei_d1;
432// ----------------------------------------------------------------------------
433// Combinational DMU to SIU xface
434// ----------------------------------------------------------------------------
435
436assign dsn_sii_cmd[7] = d2j_cmd[3] ; // PIO rd completion
437assign dsn_sii_cmd[6] = ~d2j_cmd[3] & ~d2j_cmd[2] & ~d2j_cmd[1]; // posted bit, assert for writes
438assign dsn_sii_cmd[5] = (~d2j_cmd[3] & d2j_cmd[1]) | d2j_cmd[3] ; // DMA rd request + pio_rd_cpl
439assign dsn_sii_cmd[4] = ~d2j_cmd[3] & ~d2j_cmd[1] & d2j_cmd[0]; // DMA write bytemasks are active
440assign dsn_sii_cmd[3] = ~d2j_cmd[3] & ~d2j_cmd[2] ; // all DMA's
441assign dsn_sii_cmd[2] = d2j_cmd[3] || (~d2j_cmd[3] && d2j_cmd[2]) ; // Int Mondo, or Rd cpl
442assign dsn_sii_cmd[1:0] = 2'b0;
443assign dsn_sii_to = d2j_cmd[3] & d2j_cmd[1] & ~d2j_cmd[0];
444assign dsn_sii_be = d2j_cmd[3] & d2j_cmd[1] & d2j_cmd[0];
445assign dsn_sii_ue = 1'b0;
446// if pio_rd_cpl set bit 15 of the ctag
447assign ctag_to_siu[15:0] = d2j_cmd[3] ? {1'b1,d2j_ctag[14:0]} : d2j_ctag[15:0];
448// generate parity and ecc on header bits
449 assign hdr_ecc[5:0] = gen_chk (ctag_to_siu[15:0]);
450// note: d2j_addr[33:0] is system address bits [39:6], and [5:0] are always force to zero in the outgoing header
451 assign adr_par[1] = ~^{d2j_addr[33],d2j_addr[31],d2j_addr[29],d2j_addr[27],d2j_addr[25],d2j_addr[23],
452 d2j_addr[21],d2j_addr[19],d2j_addr[17],d2j_addr[15],d2j_addr[13],d2j_addr[11],
453 d2j_addr[09],d2j_addr[07],d2j_addr[05],d2j_addr[03],d2j_addr[01]};
454 assign adr_par[0] = ~^{d2j_addr[32],d2j_addr[30],d2j_addr[28],d2j_addr[26],d2j_addr[24],d2j_addr[22],
455 d2j_addr[20],d2j_addr[18],d2j_addr[16],d2j_addr[14],d2j_addr[12],d2j_addr[10],
456 d2j_addr[08],d2j_addr[06],d2j_addr[04],d2j_addr[02],d2j_addr[00]};
457 assign cmd_par = ~^{dsn_sii_cmd[7:0]};
458assign dsn_sii_hdr[127:0] = {dsn_sii_cmd[7:0], // hdr [127:120]
459 {35'b0}, // hdr [119:85]
460 adr_par, // hdr [84:83]
461 dsn_sii_to,dsn_sii_be,dsn_sii_ue, // hdr [82:80]
462 ctag_to_siu[15:0], // hdr [79:64]
463 1'b0,cmd_par,hdr_ecc[5:0],{16'b0}, // hdr [63:40]
464 d2j_addr[33:0], // hdr [39:6]
465 {6'b0}};
466// add a 0-in checker to verify pio return bmsk is only valid on either upper or lower 64 bits(see above)
467// see ncu_dmu logic before for pio_cpl_bus_align generation
468// if pio_cpl_bus_align[1]==1 then 16 byte pio cpl, else pio_cpl_bus_align[0] tells how to duplicate 8 bytes
469assign d2j_pio_data[127:0] = pio_cpl_bus_align[1] ? d2j_data_d1[127:0] : (pio_cpl_bus_align[0] ?
470 {d2j_data_d1[63:0],d2j_data_d1[63:0]} :
471 {d2j_data_d1[127:64],d2j_data_d1[127:64]} ) ;
472//
473// BP 10-14-04 recalculate parity 2 per 32 bits, 1 or odd bits, 1 for even bits
474// as per Hunter's request, if we detect a parity error from the DIU rams, flip parity dmu_sii_parity[0].
475// BP 10-14-04 do a parity check of the data from DIU, report any errors to NCU and flip dmu_sii_parity[0] if error found
476assign calc_d2j_data_par[0] = ~^d2j_bmsk[15:0]; // if parity error in bmsk also cause error to SII
477assign calc_d2j_data_par[1] = ~^d2j_data[31:0];
478assign calc_d2j_data_par[2] = ~^d2j_data[63:32];
479assign calc_d2j_data_par[3] = ~^d2j_data[95:64];
480assign calc_d2j_data_par[4] = ~^d2j_data[127:96];
481assign force_dmu_sii_bad_par = d2j_data_vld & ( (calc_d2j_data_par[0] ^ d2j_data_par[0]) |
482 (calc_d2j_data_par[1] ^ d2j_data_par[1]) |
483 (calc_d2j_data_par[2] ^ d2j_data_par[2]) |
484 (calc_d2j_data_par[3] ^ d2j_data_par[3]) |
485 (calc_d2j_data_par[4] ^ d2j_data_par[4]) );
486assign dmu_sii_parity[0] = ( force_dmu_sii_bad_par_d1 ^
487 (~^{d2j_data_out[30],d2j_data_out[28],d2j_data_out[26],d2j_data_out[24],
488 d2j_data_out[22],d2j_data_out[20],d2j_data_out[18],d2j_data_out[16],
489 d2j_data_out[14],d2j_data_out[12],d2j_data_out[10],d2j_data_out[08],
490 d2j_data_out[06],d2j_data_out[04],d2j_data_out[02],d2j_data_out[00]} ));
491assign dmu_sii_parity[1] = ~^{d2j_data_out[31],d2j_data_out[29],d2j_data_out[27],d2j_data_out[25],
492 d2j_data_out[23],d2j_data_out[21],d2j_data_out[19],d2j_data_out[17],
493 d2j_data_out[15],d2j_data_out[13],d2j_data_out[11],d2j_data_out[09],
494 d2j_data_out[07],d2j_data_out[05],d2j_data_out[03],d2j_data_out[01]};
495assign dmu_sii_parity[2] = ~^{d2j_data_out[62],d2j_data_out[60],d2j_data_out[58],d2j_data_out[56],
496 d2j_data_out[54],d2j_data_out[52],d2j_data_out[50],d2j_data_out[48],
497 d2j_data_out[46],d2j_data_out[44],d2j_data_out[42],d2j_data_out[40],
498 d2j_data_out[38],d2j_data_out[36],d2j_data_out[34],d2j_data_out[32]};
499assign dmu_sii_parity[3] = ~^{d2j_data_out[63],d2j_data_out[61],d2j_data_out[59],d2j_data_out[57],
500 d2j_data_out[55],d2j_data_out[53],d2j_data_out[51],d2j_data_out[49],
501 d2j_data_out[47],d2j_data_out[45],d2j_data_out[43],d2j_data_out[41],
502 d2j_data_out[39],d2j_data_out[37],d2j_data_out[35],d2j_data_out[33]};
503assign dmu_sii_parity[4] = ~^{d2j_data_out[94],d2j_data_out[92],d2j_data_out[90],d2j_data_out[88],
504 d2j_data_out[86],d2j_data_out[84],d2j_data_out[82],d2j_data_out[80],
505 d2j_data_out[78],d2j_data_out[76],d2j_data_out[74],d2j_data_out[72],
506 d2j_data_out[70],d2j_data_out[68],d2j_data_out[66],d2j_data_out[64]};
507assign dmu_sii_parity[5] = ~^{d2j_data_out[95],d2j_data_out[93],d2j_data_out[91],d2j_data_out[89],
508 d2j_data_out[87],d2j_data_out[85],d2j_data_out[83],d2j_data_out[81],
509 d2j_data_out[79],d2j_data_out[77],d2j_data_out[75],d2j_data_out[73],
510 d2j_data_out[71],d2j_data_out[69],d2j_data_out[67],d2j_data_out[65]};
511assign dmu_sii_parity[6] = ~^{d2j_data_out[126],d2j_data_out[124],d2j_data_out[122],d2j_data_out[120],
512 d2j_data_out[118],d2j_data_out[116],d2j_data_out[114],d2j_data_out[112],
513 d2j_data_out[110],d2j_data_out[108],d2j_data_out[106],d2j_data_out[104],
514 d2j_data_out[102],d2j_data_out[100],d2j_data_out[98],d2j_data_out[96]};
515assign dmu_sii_parity[7] = ~^{d2j_data_out[127],d2j_data_out[125],d2j_data_out[123],d2j_data_out[121],
516 d2j_data_out[119],d2j_data_out[117],d2j_data_out[115],d2j_data_out[113],
517 d2j_data_out[111],d2j_data_out[109],d2j_data_out[107],d2j_data_out[105],
518 d2j_data_out[103],d2j_data_out[101],d2j_data_out[99],d2j_data_out[97]};
519
520assign dmu_sii_be_parity = dmu_sii_parity_be;
521assign d2j_data_out[127:0] = dsn_sii_cmd_7 ? d2j_pio_data[127:0] : d2j_data_d1[127:0];
522assign dmu_sii_data[127:0] = d2j_cmd_vld ? dsn_sii_hdr[127:0] : d2j_data_out[127:0];
523assign dmu_sii_hdr_vld = d2j_cmd_vld;
524assign dmu_sii_reqbypass = d2j_cmd[3] && d2j_cmd_vld;
525assign dmu_sii_datareq = (d2j_cmd[3] || // PIO rd cpl decode
526 (~d2j_cmd[3] && ~d2j_cmd[1])) && d2j_cmd_vld; // DMA wrt decodes
527assign dmu_sii_datareq16 = (d2j_cmd[3] || // PIO rd cpl decode
528 (~d2j_cmd[3] && d2j_cmd[2])) && d2j_cmd_vld; // INT decode
529// ----------------------------------------------------------------------------
530// Combinational SIU to DMU xface
531// ----------------------------------------------------------------------------
532// note: the SIO sends a header followed by 4 data beats, thus flop the header, but then just
533// pass the data through without flopping
534
535always @(posedge l1clk )
536 if (~rst_l) begin
537 sio_dmu_ue <= 1'b0;
538 sio_dmu_de <= 1'b0;
539 sio_dmc_tag[15:0] <= 16'b0;
540 sio_dmc_tag_ecc[5:0] <= 6'b0;
541 sio_dmu_hdr_vld_d1 <= 1'b0;
542 end
543 else begin
544 if (sio_dmu_hdr_vld ) sio_dmu_ue <= sio_dmu_data[81];
545 if (sio_dmu_hdr_vld ) sio_dmu_de <= sio_dmu_data[80];
546 if (sio_dmu_hdr_vld ) sio_dmc_tag[15:0] <= sio_dmu_data[79:64];
547 if (sio_dmu_hdr_vld ) sio_dmc_tag_ecc[5:0] <= sio_dmu_data[61:56];
548 sio_dmu_hdr_vld_d1 <= sio_dmu_hdr_vld;
549 enable_pe_err[0] <= sio_dmu_hdr_vld ;
550 enable_pe_err[1] <= enable_pe_err[0] ;
551 enable_pe_err[2] <= enable_pe_err[1] ;
552 enable_pe_err[3] <= enable_pe_err[2] ;
553 end
554
555// use a function to check the ecc on sio_dmc_tag[15:0] and return corrected data
556
557 assign sio_dsn_hdr_ecc[17:0] = gen_correct (sio_dmc_tag[15:0],sio_dmc_tag_ecc[5:0]);
558 assign dmu_ncu_ctag_ue_in = sio_dmu_hdr_vld_d1 & ( (sio_dsn_hdr_ecc[17] & ~sio_dmu_ue)
559 | ncu_dmu_ctag_uei_d1);
560 assign dmu_ncu_ctag_ce_in = sio_dmu_hdr_vld_d1 & ( (sio_dsn_hdr_ecc[16] )
561 | ncu_dmu_ctag_cei_d1);
562 assign sio_dmc_tag_corrected[15:0] = sio_dsn_hdr_ecc[15:0];
563
564assign j2d_d_data[127:0] = sio_dmu_data[127:0]; // pass-through no flop
565// check the incoming parity from the sio, and then re-generate parity for DMU, if incoming parity
566// error is detected, "or" into j2d_d_data_err, which causes the poison bit in the pci-x header(via ilu/tlu)
567assign calc_sio_dmu_data_par[0] = ~^{sio_dmu_data[30],sio_dmu_data[28],sio_dmu_data[26],sio_dmu_data[24],
568 sio_dmu_data[22],sio_dmu_data[20],sio_dmu_data[18],sio_dmu_data[16],
569 sio_dmu_data[14],sio_dmu_data[12],sio_dmu_data[10],sio_dmu_data[08],
570 sio_dmu_data[06],sio_dmu_data[04],sio_dmu_data[02],sio_dmu_data[00]} ;
571assign calc_sio_dmu_data_par[1] = ~^{sio_dmu_data[31],sio_dmu_data[29],sio_dmu_data[27],sio_dmu_data[25],
572 sio_dmu_data[23],sio_dmu_data[21],sio_dmu_data[19],sio_dmu_data[17],
573 sio_dmu_data[15],sio_dmu_data[13],sio_dmu_data[11],sio_dmu_data[09],
574 sio_dmu_data[07],sio_dmu_data[05],sio_dmu_data[03],sio_dmu_data[01]};
575assign calc_sio_dmu_data_par[2] = ~^{sio_dmu_data[62],sio_dmu_data[60],sio_dmu_data[58],sio_dmu_data[56],
576 sio_dmu_data[54],sio_dmu_data[52],sio_dmu_data[50],sio_dmu_data[48],
577 sio_dmu_data[46],sio_dmu_data[44],sio_dmu_data[42],sio_dmu_data[40],
578 sio_dmu_data[38],sio_dmu_data[36],sio_dmu_data[34],sio_dmu_data[32]};
579assign calc_sio_dmu_data_par[3] = ~^{sio_dmu_data[63],sio_dmu_data[61],sio_dmu_data[59],sio_dmu_data[57],
580 sio_dmu_data[55],sio_dmu_data[53],sio_dmu_data[51],sio_dmu_data[49],
581 sio_dmu_data[47],sio_dmu_data[45],sio_dmu_data[43],sio_dmu_data[41],
582 sio_dmu_data[39],sio_dmu_data[37],sio_dmu_data[35],sio_dmu_data[33]};
583assign calc_sio_dmu_data_par[4] = ~^{sio_dmu_data[94],sio_dmu_data[92],sio_dmu_data[90],sio_dmu_data[88],
584 sio_dmu_data[86],sio_dmu_data[84],sio_dmu_data[82],sio_dmu_data[80],
585 sio_dmu_data[78],sio_dmu_data[76],sio_dmu_data[74],sio_dmu_data[72],
586 sio_dmu_data[70],sio_dmu_data[68],sio_dmu_data[66],sio_dmu_data[64]};
587assign calc_sio_dmu_data_par[5] = ~^{sio_dmu_data[95],sio_dmu_data[93],sio_dmu_data[91],sio_dmu_data[89],
588 sio_dmu_data[87],sio_dmu_data[85],sio_dmu_data[83],sio_dmu_data[81],
589 sio_dmu_data[79],sio_dmu_data[77],sio_dmu_data[75],sio_dmu_data[73],
590 sio_dmu_data[71],sio_dmu_data[69],sio_dmu_data[67],sio_dmu_data[65]};
591assign calc_sio_dmu_data_par[6] = ~^{sio_dmu_data[126],sio_dmu_data[124],sio_dmu_data[122],sio_dmu_data[120],
592 sio_dmu_data[118],sio_dmu_data[116],sio_dmu_data[114],sio_dmu_data[112],
593 sio_dmu_data[110],sio_dmu_data[108],sio_dmu_data[106],sio_dmu_data[104],
594 sio_dmu_data[102],sio_dmu_data[100],sio_dmu_data[98],sio_dmu_data[96]};
595assign calc_sio_dmu_data_par[7] = ~^{sio_dmu_data[127],sio_dmu_data[125],sio_dmu_data[123],sio_dmu_data[121],
596 sio_dmu_data[119],sio_dmu_data[117],sio_dmu_data[115],sio_dmu_data[113],
597 sio_dmu_data[111],sio_dmu_data[109],sio_dmu_data[107],sio_dmu_data[105],
598 sio_dmu_data[103],sio_dmu_data[101],sio_dmu_data[99],sio_dmu_data[97]};
599
600assign dmu_ncu_d_pe_in = (sio_dsn_pe & ~sio_dmu_de) ||
601 (|enable_pe_err[3:0] & ncu_dmu_d_pei_d1); // only assert pe if data is vld
602 // note: use enable_pe_err[3:0] not j2d_d_data_vld because
603 // if there is an error in the tag(ie. ue), the packet is dropped going back
604 // to dmc, and thus it would not be asserted
605assign sio_dsn_pe = j2d_d_data_vld & ( // only assert pe if data is vld
606 ( calc_sio_dmu_data_par[0] ^ sio_dmu_parity[0] ) |
607 ( calc_sio_dmu_data_par[1] ^ sio_dmu_parity[1] ) |
608 ( calc_sio_dmu_data_par[2] ^ sio_dmu_parity[2] ) |
609 ( calc_sio_dmu_data_par[3] ^ sio_dmu_parity[3] ) |
610 ( calc_sio_dmu_data_par[4] ^ sio_dmu_parity[4] ) |
611 ( calc_sio_dmu_data_par[5] ^ sio_dmu_parity[5] ) |
612 ( calc_sio_dmu_data_par[6] ^ sio_dmu_parity[6] ) |
613 ( calc_sio_dmu_data_par[7] ^ sio_dmu_parity[7] ) );
614
615// force j2d_d_data_par[0] to be in err for tablewalks if ncu_dmu_d_pei is asserted
616assign j2d_d_data_par[0] = ~^({sio_dmu_data[31:0]}); // flip to force bad par
617 // note good parity is generated no matter
618assign j2d_d_data_par[1] = ~^(sio_dmu_data[63:32]); // what, but SW knows because of signaling
619assign j2d_d_data_par[2] = ~^(sio_dmu_data[95:64]); // to NCU and data poison to ilu/tlu
620assign j2d_d_data_par[3] = ~^(sio_dmu_data[127:96]);
621assign j2d_d_data_err = j2d_d_data_vld & // sio_dmu_de is for all l2$ DATA errors
622 (sio_dmu_de | sio_dsn_pe | ncu_dmu_d_pei_d1);
623 // sio_dsn_pe is for locally detected pe's
624
625// generate 4 data valid's
626 always @ (posedge l1clk)
627 if (~rst_l) begin
628 hdr_cnt[2:0] <= 3'b0;
629 end
630 else begin
631 hdr_cnt[2:0] <= nxt_hdr_cnt[2:0];
632 end
633
634always @(hdr_cnt or reset or sio_dmu_hdr_vld or sio_dmu_hdr_vld_d1 or sio_dmu_ue or sio_dsn_hdr_ecc ) begin
635 if ( reset) begin
636 nxt_hdr_cnt[2:0] = 3'b000;
637 end
638 else if (sio_dmu_hdr_vld )begin
639 nxt_hdr_cnt[2:0] = 3'b100;
640 end
641 else if ((sio_dmu_ue | sio_dsn_hdr_ecc[17]) & sio_dmu_hdr_vld_d1 )begin // detect error 1 cycle late
642 nxt_hdr_cnt[2:0] = 3'b000; // so bak to 0 here
643 end
644 else if ( |hdr_cnt[2:0] != 1'b0 ) begin
645 nxt_hdr_cnt[2:0] = hdr_cnt[2:0] - 3'b001;
646 end
647 else nxt_hdr_cnt[2:0] = hdr_cnt[2:0];
648 end
649
650assign j2d_d_data_vld = (|hdr_cnt[2:0]
651 & ~(sio_dmu_ue | sio_dsn_hdr_ecc[17]) ) // this term blocks the first j2d_d_data_vld
652 & ~ncu_dmu_ctag_uei_d1 ; // do not return if forcing an error on credit id
653// get j2d_di_cmd from the SIO dma rd cpl header, or the mondo return fifo
654wire en_dma_rd_rtn; // note: in FIRE j2d_di_cmd_vld is asserted on the first j2d_d_data_vld
655 // but from the SIO the sio_dmu_hdr_vld is 1 cycle before the data
656 // so this creates a hole to return mondo's,
657assign en_dma_rd_rtn = (sio_dmu_hdr_vld_d1 &
658 ~((sio_dmu_ue | sio_dsn_hdr_ecc[17]) | // disable vld if ue
659 ncu_dmu_ctag_uei_d1) ); // disable vld return if ncu forcing errors
660
661assign j2d_di_cmd[1:0] = en_dma_rd_rtn ? {1'b0,( sio_dmu_de)} : {1'b1,data_out[7]};
662assign j2d_di_ctag[15:0] = en_dma_rd_rtn ? sio_dmc_tag_corrected[15:0] : {1'b0,data_out[5:2],8'b0,data_out[1:0],1'b0};
663assign mondo_cmd_vld = !fifo_empty && !j2d_d_data_vld;
664assign read = !fifo_empty && !j2d_d_data_vld;
665// note: if sio_dmu_ue, ie. ctag ecc or address pe error, then do not return this transaction, otherwise
666// the scoreboard could get corrupted, SW will have to intervene and fix.
667// this includes the ue from SIO as well as local ctag ecc ue's
668// also don't return if forcing pe's from ncu for test
669
670assign j2d_di_cmd_vld = en_dma_rd_rtn // only return if no errors
671 | mondo_cmd_vld; // note if ncu mondo ack had a pe it would not
672 // even gone into the fifo, so do j2d_di_cmd_vld
673
674// ----------------------------------------------------------------------------
675// Combinational MONDO ack FIFO from NCU
676// ----------------------------------------------------------------------------
677// check the incoming parity, and if in error, then drop the write into the fifo
678wire calc_ncu_dmu_mondo_id_par;
679assign calc_ncu_dmu_mondo_id_par = ~^ncu_dmu_mondo_id[5:0];
680assign dmu_ncu_ncucr_pe_in = (ncu_dmu_mondo_ack || ncu_dmu_mondo_nack) &
681 ((calc_ncu_dmu_mondo_id_par ^ ncu_dmu_mondo_id_par)
682 | ncu_dmu_ncucr_pei_d1 );
683assign data_in[7:0] = {ncu_dmu_mondo_ack,ncu_dmu_mondo_nack,ncu_dmu_mondo_id[5:0]};
684assign write = (ncu_dmu_mondo_ack || ncu_dmu_mondo_nack) &
685 ~((calc_ncu_dmu_mondo_id_par ^ ncu_dmu_mondo_id_par) | // no int ack return if parity error
686 ncu_dmu_ncucr_pei_d1) ; // or if forcing this error from ncu
687
688dmu_dsn_mondo_fifo mondo_fifo (
689 .clk (l1clk),
690 .rst_l (rst_l),
691 .data_in (data_in[7:0]),
692 .write (write),
693 .data_out (data_out[7:0]),
694 .read (read),
695 .fifo_empty (fifo_empty)
696 );
697
698
699// ----------------------------------------------------------------------------
700// Combinational NCU to DMU PIO xface
701// ----------------------------------------------------------------------------
702wire [1:0] p_data_par;
703assign j2d_p_data[127:0] = {ncu_dmu_pio_data[63:0],ncu_dmu_pio_data[63:0]}; // duplicate 64 bits,only 8 byte writes
704assign p_data_par[0] = ~^ncu_dmu_pio_data[31:0];
705assign p_data_par[1] = ~^ncu_dmu_pio_data[63:32];
706assign j2d_p_data_par[3:0] = {p_data_par[1:0],p_data_par[1:0]}; // duplicate parity bits
707always @(posedge l1clk )
708 if (~rst_l) begin
709 pio_credit_id[3:0] <= 4'b0;
710 pio_read <= 1'b0;
711 pio_byte_cnt[7:0] <= 8'b0;
712 pio_cmd_map[1:0] <= 2'b0;
713 pio_id[6:0] <= 7'b0;
714 pio_pa[42:0] <= 43'b0;
715 j2d_p_cmd_vld <= 1'b0;
716 mmu_addr_vld <= 1'b0;
717 end
718 else begin
719 if (ncu_dmu_pio_hdr_vld ) pio_read <= ncu_dmu_pio_data[60];
720 if (ncu_dmu_pio_hdr_vld ) pio_credit_id[3:0] <= ncu_dmu_pio_data[59:56];
721 if (ncu_dmu_pio_hdr_vld ) pio_byte_cnt[7:0] <= ncu_dmu_pio_data[55:48];
722 if (ncu_dmu_pio_hdr_vld ) pio_id[6:0] <= ncu_dmu_pio_data[46:40];
723 if (ncu_dmu_pio_hdr_vld ) pio_cmd_map[1:0] <= ncu_dmu_pio_data[37:36];
724 if (ncu_dmu_pio_hdr_vld |
725 ncu_dmu_mmu_addr_vld ) pio_pa[42:0] <= ncu_dmu_pio_data[42:0]; // for hdr and mmu inv.
726 j2d_p_cmd_vld <= ncu_dmu_pio_hdr_vld;
727 mmu_addr_vld <= ncu_dmu_mmu_addr_vld;
728 end
729
730assign j2d_p_data_vld = j2d_p_cmd_vld && !pio_read;
731assign j2d_p_ctag[10:0]= {pio_credit_id[3:0],pio_id[6:0]};
732assign j2d_p_addr[35:3]= pio_pa[35:3];
733assign j2d_p_addr[2] = pio_read ? pio_pa[2] :
734 ( (|pio_byte_cnt[7:4] || ~|pio_byte_cnt[7:0]) ? 1'b0 : 1'b1) ;
735assign j2d_p_addr[1:0]= pio_pa[1:0];
736// if a PIO write use pio_byte_cnt directly as the bytemask, if a read see below
737assign j2d_p_bmsk[15:0]= pio_bmsk[15:0];
738
739// note: see pg. 7.622 of fire MAS for bmask description, thus bmsk[0] is for bits [7:0](word 15)ie. the data is
740// big endian, but the bmsk is reversed.
741assign pio_bmsk_sel[2:0] = {pio_read,pio_byte_cnt[2],j2d_p_addr[3]};
742always @(pio_bmsk_sel or pio_byte_cnt or pio_rd_bmsk)begin
743 pio_bmsk[15:0] = {16{1'b0}};
744 case ( pio_bmsk_sel) //0in case -full -parallel
745 3'b000: pio_bmsk = {pio_byte_cnt[7:0],{8{1'b0}}}; // pio write,adr[3]=0, so msbytes
746 3'b010: pio_bmsk = {pio_byte_cnt[7:0],{8{1'b0}}}; // pio write,adr[3]=0, so msbytes
747 3'b001: pio_bmsk = {{8{1'b0}},pio_byte_cnt[7:0]}; // pio write,adr[3]=1, so lsbytes
748 3'b011: pio_bmsk = {{8{1'b0}},pio_byte_cnt[7:0]}; // pio write,adr[3]=1, so lsbytes
749 3'b100: pio_bmsk = {pio_rd_bmsk[7:0],{8{1'b0}}}; // pio read, <=8bytes use pio_rd_bmsk below
750 3'b101: pio_bmsk = {{8{1'b0}},pio_rd_bmsk[7:0]}; // pio read, <=8bytes use pio_rd_bmsk below
751 3'b110: pio_bmsk = ({16{1'b1}}); // pio read, 16bytes turn on all bits
752 3'b111: pio_bmsk = ({16{1'b1}}); // pio read, 16bytes turn on all bits
753// default: pio_bmsk = {16{1'bx}};
754 endcase
755end
756
757// now figure out the j2d cmd from the ncu header
758assign j2d_p_cmd[3] = pio_read;
759assign j2d_p_cmd[2] = 1'b1; // always 16 bytes
760assign j2d_p_cmd[1] = (!pio_cmd_map[1] && pio_cmd_map[0]) ||
761 (!pio_cmd_map[1] && !pio_cmd_map[0]) ;
762assign j2d_p_cmd[0] = (pio_cmd_map[1] && !pio_cmd_map[0]) ||
763 (!pio_cmd_map[1] && !pio_cmd_map[0]) ;
764// now figure out the bmsk for PIO read
765always @(pio_pa[2:0] or pio_byte_cnt[1:0])begin
766 pio_rd_bmsk[7:0] = 8'b00000000 ;
767 case(pio_pa[2:0]) //0in case -full -parallel
768 3'b000: begin
769 if(pio_byte_cnt[1:0]==2'b11) pio_rd_bmsk[7:0] = 8'b11111111 ;
770 else if (pio_byte_cnt[1:0]==2'b10) pio_rd_bmsk[7:0] = 8'b11110000 ;
771 else if (pio_byte_cnt[1:0]==2'b01) pio_rd_bmsk[7:0] = 8'b11000000 ;
772 else if (pio_byte_cnt[1:0]==2'b00) pio_rd_bmsk[7:0] = 8'b10000000 ;
773 else pio_rd_bmsk[7:0] = 8'b00000000 ;
774 end
775 3'b001: begin
776 if(pio_byte_cnt[1:0]==2'b11) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
777 else if (pio_byte_cnt[1:0]==2'b10) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
778 else if (pio_byte_cnt[1:0]==2'b01) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
779 else if (pio_byte_cnt[1:0]==2'b00) pio_rd_bmsk[7:0] = 8'b01000000 ;
780 else pio_rd_bmsk[7:0] = 8'b00000000 ;
781 end
782 3'b010: begin
783 if(pio_byte_cnt[1:0]==2'b11) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
784 else if (pio_byte_cnt[1:0]==2'b10) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
785 else if (pio_byte_cnt[1:0]==2'b01) pio_rd_bmsk[7:0] = 8'b00110000 ;
786 else if (pio_byte_cnt[1:0]==2'b00) pio_rd_bmsk[7:0] = 8'b00100000 ;
787 else pio_rd_bmsk[7:0] = 8'b00000000 ;
788 end
789 3'b011: begin
790 if(pio_byte_cnt[1:0]==2'b11) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
791 else if (pio_byte_cnt[1:0]==2'b10) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
792 else if (pio_byte_cnt[1:0]==2'b01) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
793 else if (pio_byte_cnt[1:0]==2'b00) pio_rd_bmsk[7:0] = 8'b00010000 ;
794 else pio_rd_bmsk[7:0] = 8'b00000000 ;
795 end
796 3'b100: begin
797 if(pio_byte_cnt[1:0]==2'b11) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
798 else if (pio_byte_cnt[1:0]==2'b10) pio_rd_bmsk[7:0] = 8'b00001111 ;
799 else if (pio_byte_cnt[1:0]==2'b01) pio_rd_bmsk[7:0] = 8'b00001100 ;
800 else if (pio_byte_cnt[1:0]==2'b00) pio_rd_bmsk[7:0] = 8'b00001000 ;
801 else pio_rd_bmsk[7:0] = 8'b00000000 ;
802 end
803 3'b101: begin
804 if(pio_byte_cnt[1:0]==2'b11) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
805 else if (pio_byte_cnt[1:0]==2'b10) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
806 else if (pio_byte_cnt[1:0]==2'b01) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
807 else if (pio_byte_cnt[1:0]==2'b00) pio_rd_bmsk[7:0] = 8'b00000100 ;
808 else pio_rd_bmsk[7:0] = 8'b00000000 ;
809 end
810 3'b110: begin
811 if(pio_byte_cnt[1:0]==2'b11) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
812 else if (pio_byte_cnt[1:0]==2'b10) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
813 else if (pio_byte_cnt[1:0]==2'b01) pio_rd_bmsk[7:0] = 8'b00000011 ;
814 else if (pio_byte_cnt[1:0]==2'b00) pio_rd_bmsk[7:0] = 8'b00000010 ;
815 else pio_rd_bmsk[7:0] = 8'b00000000 ;
816 end
817 3'b111: begin
818 if(pio_byte_cnt[1:0]==2'b11) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
819 else if (pio_byte_cnt[1:0]==2'b10) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
820 else if (pio_byte_cnt[1:0]==2'b01) pio_rd_bmsk[7:0] = 8'b00000000 ; //error condition
821 else if (pio_byte_cnt[1:0]==2'b00) pio_rd_bmsk[7:0] = 8'b00000001 ;
822 else pio_rd_bmsk[7:0] = 8'b00000000 ;
823 end
824// default: pio_rd_bmsk[7:0] = 8'bxxxxxxxx;
825 endcase
826 end
827
828// logic to store ncu_dmu_pio_data[3] which is the pio address bit3 along with the credit_id, then when
829// the pio rd completion is returned to the sii, replicate the valid 64 bits on both halves of the 128 bit bus
830// if pio addr[3] =0 then it expects data on [127:63]
831// create a 2 bit 16 entry ram, bit 1 tells if 16 byte reads, bit 0, indicates if <=8byte reads how to duplicate the bus
832
833reg [1:0] pio_crdit_ram [0:15];
834
835assign pio_cpl_bus_align[1:0] = pio_crdit_ram[d2j_ctag_d1[11:8]]; // after thread_id changes
836// if pio cmd vld and it is a pio rd, then byte count bit 2 and store pa[3] to be used on pio_rd cpl to sii to
837// duplicate the data bus if 8 or less byte read, and if 16 byte read, leave as is
838always @(posedge l1clk)
839 if (~rst_l)
840 begin : scb_reg_reset
841 integer i;
842 for (i=0; i<16; i=i+1)
843 begin
844 pio_crdit_ram[i] <= 2'b0;
845 end
846 end
847 else if(ncu_dmu_pio_hdr_vld && ncu_dmu_pio_data[60]) begin
848 pio_crdit_ram[ncu_dmu_pio_data[59:56]] <= {ncu_dmu_pio_data[50],ncu_dmu_pio_data[3]}; // [1]=16byte,[3]=adr[2]
849 end
850
851// BP n2 10-26-04 monitor to check that the NCU only emits unique id's for pio rds
852/* 0in scoreboard -rx_id ncu_dmu_pio_data[59:56]
853 -rx (ncu_dmu_pio_hdr_vld && ncu_dmu_pio_data[60])
854 -tx_id d2j_ctag[11:8]
855 -tx (d2j_cmd_vld & ( d2j_cmd[3] == 1'b1 ) )
856 -name dsn_ncu_sii_scbd
857*/
858
859// forward the mmu invalidate
860
861assign j2d_mmu_addr_vld = mmu_addr_vld;
862assign j2d_mmu_addr[42:6] = pio_pa[42:6];
863
864// ----------------------------------------------------------------------------
865// Combinational NCU to DMU DMA wrack xface
866// ----------------------------------------------------------------------------
867wire calc_sii_dmu_wrack_tag_par;
868assign j2d_d_wrack_tag[3:0] = sii_dmu_wrack_tag[3:0];
869assign calc_sii_dmu_wrack_tag_par = ~^sii_dmu_wrack_tag[3:0];
870// BP 10-15-04 if detect parity error, then drop the credit_id return so as not to corrupt the scoreboard
871
872assign j2d_d_wrack_vld = sii_dmu_wrack_vld &
873 ~((calc_sii_dmu_wrack_tag_par ^ sii_dmu_wrack_par) | // do not return cr id if pe
874 ncu_dmu_siicr_pei_d1 ); // or if ncu is forcing this error
875assign dmu_ncu_siicr_pe_in = sii_dmu_wrack_vld & ((calc_sii_dmu_wrack_tag_par ^ sii_dmu_wrack_par)
876 | ncu_dmu_siicr_pei_d1); // force pe if NCU asserts this
877// ----------------------------------------------------------------------------
878// Combinational DMU to NCU PIO wrack xface
879// ----------------------------------------------------------------------------
880
881assign dmu_ncu_wrack_tag[3:0] = d2j_p_wrack_tag[3:0];
882assign dmu_ncu_wrack_par = ~^d2j_p_wrack_tag[3:0];
883assign dmu_ncu_wrack_vld = d2j_p_wrack_vld;
884
885// ----------------------------------------------------------------------------
886// function to generate ecc for DSN to SII header
887// ----------------------------------------------------------------------------
888
889 function [5:0] gen_chk;
890 input [15:0] di;
891
892 reg [5:0] chk;
893begin
894 chk[0] = ^{di[15],di[13],di[11],di[10],di[8],di[6],di[4],di[3],di[1],di[0]};
895 chk[1] = ^{di[13],di[12],di[10],di[9],di[6],di[5],di[3],di[2],di[0]};
896 chk[2] = ^{di[15],di[14],di[10],di[9],di[8],di[7],di[3],di[2],di[1]};
897 chk[3] = ^{di[10],di[9],di[8],di[7],di[6],di[5],di[4]};
898 chk[4] = ^{di[15],di[14],di[13],di[12],di[11]};
899 chk[5] = ^{di[15],di[14],di[13],di[12],di[11],di[10],di[9],di[8],
900 di[7],di[6],di[5],di[4],di[3],di[2],di[1],di[0],
901 chk[0],chk[1],chk[2],chk[3],chk[4]};
902
903 gen_chk[5:0] = {chk[5],chk[4],chk[3],chk[2],chk[1],chk[0]};
904end
905
906 endfunction //gen_chk
907
908// ----------------------------------------------------------------------------
909// function to correct data from ecc for SIO to DSN header
910// ----------------------------------------------------------------------------
911
912 function [17:0] gen_correct;
913 input [15:0] di_tag;
914 input [5:0] di_ecc;
915
916 reg [15:0] c_data;
917 reg [5:0] err;
918 reg [5:0] chk;
919 reg ce, ue;
920// reg no_error;
921begin
922 chk[0] = ^{di_tag[15],di_tag[13],di_tag[11],di_tag[10],di_tag[8],di_tag[6],di_tag[4],di_tag[3],di_tag[1],di_tag[0]};
923 chk[1] = ^{di_tag[13],di_tag[12],di_tag[10],di_tag[9],di_tag[6],di_tag[5],di_tag[3],di_tag[2],di_tag[0]};
924 chk[2] = ^{di_tag[15],di_tag[14],di_tag[10],di_tag[9],di_tag[8],di_tag[7],di_tag[3],di_tag[2],di_tag[1]};
925 chk[3] = ^{di_tag[10],di_tag[9],di_tag[8],di_tag[7],di_tag[6],di_tag[5],di_tag[4]};
926 chk[4] = ^{di_tag[15],di_tag[14],di_tag[13],di_tag[12],di_tag[11]};
927 chk[5] = ^{di_tag[15],di_tag[14],di_tag[13],di_tag[12],di_tag[11],di_tag[10],di_tag[9],di_tag[8],
928 di_tag[7],di_tag[6],di_tag[5],di_tag[4],di_tag[3],di_tag[2],di_tag[1],di_tag[0],
929 di_ecc[0],di_ecc[1],di_ecc[2],di_ecc[3],di_ecc[4]};
930
931 err[0] = chk[0] ^ di_ecc[0];
932 err[1] = chk[1] ^ di_ecc[1];
933 err[2] = chk[2] ^ di_ecc[2];
934 err[3] = chk[3] ^ di_ecc[3];
935 err[4] = chk[4] ^ di_ecc[4];
936 err[5] = chk[5] ^ di_ecc[5];
937// no_error = ~|err;
938 if ( (err[4:0] <= 5'd21 ) && err[5] == 1'b1) begin
939 ce = 1'b1;
940 end
941 else begin
942 ce = 1'b0;
943 end
944 if ( ((err[4:0] != 5'b0) & err[5] == 1'b0) || (err[4:0] > 5'd21)) begin
945 ue = 1'b1;
946 end
947 else begin
948 ue = 1'b0;
949 end
950
951
952 c_data[0] = di_tag[0] ^ (err[4:0] == 5'd03);
953 c_data[1] = di_tag[1] ^ (err[4:0] == 5'd05);
954 c_data[2] = di_tag[2] ^ (err[4:0] == 5'd06);
955 c_data[3] = di_tag[3] ^ (err[4:0] == 5'd07);
956 c_data[4] = di_tag[4] ^ (err[4:0] == 5'd09);
957 c_data[5] = di_tag[5] ^ (err[4:0] == 5'd10);
958 c_data[6] = di_tag[6] ^ (err[4:0] == 5'd11);
959 c_data[7] = di_tag[7] ^ (err[4:0] == 5'd12);
960 c_data[8] = di_tag[8] ^ (err[4:0] == 5'd13);
961 c_data[9] = di_tag[9] ^ (err[4:0] == 5'd14);
962 c_data[10] = di_tag[10] ^ (err[4:0] == 5'd15);
963 c_data[11] = di_tag[11] ^ (err[4:0] == 5'd17);
964 c_data[12] = di_tag[12] ^ (err[4:0] == 5'd18);
965 c_data[13] = di_tag[13] ^ (err[4:0] == 5'd19);
966 c_data[14] = di_tag[14] ^ (err[4:0] == 5'd20);
967 c_data[15] = di_tag[15] ^ (err[4:0] == 5'd21);
968
969 gen_correct = {ue,ce,c_data[15:0]};
970
971end
972
973 endfunction //gen_chk
974
975
976// ----------------------------------------------------------------------------
977// Debug stall logic
978// ----------------------------------------------------------------------------
979reg [1:0] stall,n_stall;
980wire dmu_ingress_idle;
981reg [4:0] dbg_stall_dma;
982reg [2:0] dbg_stall_int;
983reg [4:0] n_dbg_stall_dma;
984reg [2:0] n_dbg_stall_int;
985wire dma_to_sio,int_to_sio,ncu_int_ack;
986
987 always @ (posedge l1clk)
988 if(~rst_l) begin
989 stall <= {2{1'b0}};
990 end
991 else begin
992 stall <= n_stall;
993 end
994
995always @ (stall or dbg1_dmu_stall or dbg1_dmu_resume or dmu_ingress_idle ) begin
996 case ({stall})
997 2'b00 : if (dbg1_dmu_stall) n_stall = 2'b01; // if stall request, go to stall state
998 else n_stall = 2'b00;
999 2'b01 : if (dmu_ingress_idle) n_stall = 2'b10; // if resume request, go to normal state
1000 else n_stall = 2'b01;
1001 2'b10 : n_stall = 2'b11; // transitory to get 1 wide pulse for dmu_dbg_stall_ack
1002 2'b11 : if (dbg1_dmu_resume) n_stall = 2'b00; // if resume request, go to normal state
1003 else n_stall = 2'b11;
1004 endcase
1005end
1006// indicate idle, if we are supposed to stall, all outstanding dma's/int's are done and no new one pending
1007assign dmu_ingress_idle = ~(|dbg_stall_dma) & ~(|dbg_stall_int) & ~d2j_cmd_vld & |stall;
1008assign ds2cl_stall = |stall | dbg1_dmu_stall;
1009assign dmu_dbg1_stall_ack = stall[1] & ~stall[0];
1010// ----------------------------------------------------------------------------
1011// Debug stall logic outstanding dma and int counter
1012// ----------------------------------------------------------------------------
1013
1014 always @ (posedge l1clk)
1015 if(~rst_l) begin
1016 dbg_stall_dma <= {5{1'b0}};
1017 dbg_stall_int <= {3{1'b0}};
1018 end
1019 else begin
1020 dbg_stall_dma <= n_dbg_stall_dma;
1021 dbg_stall_int <= n_dbg_stall_int;
1022 end
1023
1024assign dma_to_sio = dmu_sii_hdr_vld & dmu_sii_data[123];
1025assign int_to_sio = dmu_sii_hdr_vld & ~dmu_sii_data[127] & dmu_sii_data[122];
1026assign ncu_int_ack = (ncu_dmu_mondo_ack || ncu_dmu_mondo_nack);
1027
1028always @ (dbg_stall_dma or dma_to_sio or sii_dmu_wrack_vld or
1029 sio_dmu_hdr_vld ) begin
1030 case ({dma_to_sio,sii_dmu_wrack_vld,sio_dmu_hdr_vld})
1031 3'b000 : n_dbg_stall_dma = dbg_stall_dma; // no txn's this cycle
1032 3'b001 : n_dbg_stall_dma = dbg_stall_dma - 5'b0001; // dma rd cpl, subtr. 1
1033 3'b010 : n_dbg_stall_dma = dbg_stall_dma - 5'b0001; // dma wrack, subtr 1
1034 3'b011 : n_dbg_stall_dma = dbg_stall_dma - 5'b0010; // both rd cpl and dma wrack, subtr 2
1035 3'b100 : n_dbg_stall_dma = dbg_stall_dma + 5'b0001; // send out 1 dma, inc by 1
1036 3'b101 : n_dbg_stall_dma = dbg_stall_dma ; // send out 1, get 1 back, no change
1037 3'b110 : n_dbg_stall_dma = dbg_stall_dma ; // send out 1, get 1 back, no change
1038 3'b111 : n_dbg_stall_dma = dbg_stall_dma - 5'b0001; // send out 1, get wrack and dma rd cpl, subtr 1
1039 default : n_dbg_stall_dma = {5{1'b0}};
1040 endcase
1041 end
1042
1043always @ (dbg_stall_int or int_to_sio or ncu_int_ack ) begin
1044 case ({int_to_sio,ncu_int_ack})
1045 2'b00 : n_dbg_stall_int = dbg_stall_int; // no txn's this cycle
1046 2'b01 : n_dbg_stall_int = dbg_stall_int - 3'b01; // int ack, subtr. 1
1047 2'b10 : n_dbg_stall_int = dbg_stall_int + 3'b01; // int out inc 1
1048 2'b11 : n_dbg_stall_int = dbg_stall_int ; // both int out and int wrack, no change
1049 default : n_dbg_stall_int = {3{1'b0}};
1050 endcase
1051 end
1052
1053
1054// ----------------------------------------------------------------------------
1055// Debug bus to CRU then on to dgb.sv
1056// ----------------------------------------------------------------------------
1057//-----------------------
1058// DSN Mux Port A
1059//-----------------------
1060assign n_dbg_grp_a_2[`FIRE_DEBUG_WDTH-1:0] = {dmu_sii_hdr_vld,dmu_sii_reqbypass,dmu_sii_datareq, dmu_sii_datareq16,
1061 dsn_sii_hdr[126],dsn_sii_hdr[124],dsn_sii_hdr[123],dsn_sii_hdr[122]};
1062assign n_dbg_grp_a_3[`FIRE_DEBUG_WDTH-1:0] = {n_dbg_stall_int[2:0],n_dbg_stall_dma[4:0]};
1063always @ (cr2ds_dbg_sel_a or ucb2ctl_dbg_grp_a_1 or n_dbg_grp_a_2 or n_dbg_grp_a_3 ) begin
1064 case (cr2ds_dbg_sel_a) // synopsys parallel_case infer_mux
1065 6'h0 : n_dsn_dbg_a = {`FIRE_DEBUG_WDTH{1'b0}};
1066 6'h1 : n_dsn_dbg_a = ucb2ctl_dbg_grp_a_1;
1067 6'h2 : n_dsn_dbg_a = n_dbg_grp_a_2;
1068 6'h3 : n_dsn_dbg_a = n_dbg_grp_a_3;
1069 default : n_dsn_dbg_a = {`FIRE_DEBUG_WDTH{1'b0}};
1070 endcase
1071 end
1072
1073//-----------------------
1074// DSN Mux Port B
1075//-----------------------
1076assign n_dbg_grp_b_2[`FIRE_DEBUG_WDTH-1:0] = {sio_dmu_hdr_vld,sii_dmu_wrack_vld,ncu_dmu_mondo_ack, ncu_dmu_mondo_nack,
1077 ncu_dmu_pio_hdr_vld,pio_read,dmu_ncu_wrack_vld,1'b0};
1078
1079 always @ (cr2ds_dbg_sel_b or fsm2ctl_dbg_grp_b_1 or pkt2ctl_dbg_grp_b_1 or n_dbg_grp_b_2 ) begin
1080 case (cr2ds_dbg_sel_b) // synopsys parallel_case infer_mux
1081 6'h0 : n_dsn_dbg_b = {`FIRE_DEBUG_WDTH{1'b0}};
1082 6'h1 : n_dsn_dbg_b = {fsm2ctl_dbg_grp_b_1,pkt2ctl_dbg_grp_b_1};
1083 6'h2 : n_dsn_dbg_b = n_dbg_grp_b_2;
1084 default: n_dsn_dbg_b = {`FIRE_DEBUG_WDTH{1'b0}};
1085 endcase
1086 end
1087
1088
1089 always @ (posedge l1clk)
1090 if(~rst_l) begin
1091 ds2cr_dbg_a <= {`FIRE_DEBUG_WDTH{1'b0}};
1092 ds2cr_dbg_b <= {`FIRE_DEBUG_WDTH{1'b0}};
1093 end
1094 else begin
1095 ds2cr_dbg_a <= n_dsn_dbg_a;
1096 ds2cr_dbg_b <= n_dsn_dbg_b;
1097 end
1098
1099endmodule
1100
1101