Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / verilog / ldst_sync / ldst_lsu.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: ldst_lsu.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`ifdef CORE_0
36
37module ldst_lsu_c0 ();
38`ifndef GATESIM
39
40// common defines
41`include "defines.vh"
42`include "nas.vh"
43// PCX/CPX packet defines (see :/verif/env/common/vera/include)
44`include "ccx.vri"
45`include "cmp.vri"
46
47//---------------------
48// Load Signals
49wire load_w;
50
51wire ldi_suppress;
52wire [2:0] ldi_tid_w;
53wire [5:0] ldi_tnum_w;
54wire [39:0] ldi_pa_b;
55reg [39:0] ldi_pa_w;
56wire [1:0] ldi_size_b;
57reg [1:0] ldi_size_w;
58wire ldi_bld_b;
59wire ldi_qld_b;
60wire ldi_ldbl_b;
61wire ldi_ldd_b;
62wire ldi_atomic_b;
63wire ldi_pf_b;
64reg ldi_pf_w;
65reg [7:0] ldi_itype_w;
66reg [7:0] dsrc;
67
68wire ld_miss_b;
69reg ld_miss_w;
70reg stb_hit_w;
71wire fraw_w;
72wire hit_w;
73wire miss_w;
74wire load_data_hit;
75
76wire load_fill_e;
77reg load_fill_m;
78reg load_fill_b;
79reg load_fill_w;
80wire [2:0] ldf_tid_e;
81reg [2:0] ldf_tid_m;
82reg [2:0] ldf_tid_b;
83reg [2:0] ldf_tid_w;
84reg [5:0] ldf_tnum_w;
85wire [39:0] ldf_pa_e;
86reg [39:0] ldf_pa_m;
87reg [39:0] ldf_pa_b;
88reg [39:0] ldf_pa_w;
89
90//---------------------
91// Store Signals
92wire unflushed_store_w;
93wire store_w;
94wire sti_suppress;
95wire [2:0] sti_tid_b;
96reg [2:0] sti_tid_w;
97wire [5:0] sti_tnum_w;
98wire [39:0] sti_pa_b;
99reg [39:0] sti_pa_w;
100wire [63:0] sti_data_w;
101wire [7:0] sti_size_m;
102reg [7:0] sti_size_b;
103reg [7:0] sti_size_w;
104wire [7:0] sti_itype_w;
105reg [7:0] itype_w;
106wire [63:0] sbd_st_data_b;
107reg [63:0] sbd_st_data_w;
108wire flip_size_b;
109
110wire atomic_b;
111wire rmo_st_b;
112wire blk_inst_b;
113reg blk_inst_w;
114
115wire bst_in_prog_b;
116reg bst_in_prog_w;
117wire [39:0] bst_pa_b;
118reg [39:0] bst_pa_w;
119wire [2:0] bst_tid_b;
120reg [2:0] bst_tid_w;
121wire [39:0] st_pa_b;
122reg [39:0] st_pa_w;
123wire [2:0] st_tid_b;
124reg [2:0] st_tid_w;
125
126wire store_inv_e;
127reg store_inv_m;
128reg store_inv_b;
129reg store_inv_w;
130wire [5:0] stinv_tnum_e;
131reg [5:0] stinv_tnum_m;
132reg [5:0] stinv_tnum_b;
133reg [5:0] stinv_tnum_w;
134
135wire store_update_e;
136reg store_update_m;
137reg store_update_b;
138reg store_update_w;
139wire [2:0] stu_tid_e;
140reg [2:0] stu_tid_m;
141reg [2:0] stu_tid_b;
142reg [2:0] stu_tid_w;
143wire [5:0] stu_tnum_e;
144reg [5:0] stu_tnum_m;
145reg [5:0] stu_tnum_b;
146reg [5:0] stu_tnum_w;
147
148wire [7:0] asi_st_dequeue;
149wire [7:0] st_ack_no_asi_e;
150reg [7:0] st_ack_no_asi_m;
151reg [7:0] st_ack_no_asi_b;
152wire [7:0] store_ack_b;
153reg [7:0] store_ack_w;
154wire [7:0] st_ack_rmo_b;
155reg [7:0] st_ack_rmo_w;
156reg sta_rmo;
157reg [2:0] sta_tid;
158reg [5:0] sta_tnum;
159reg sta_suppress [0:7]; // 1 per thread
160wire st_io_asi;
161wire [2:0] st_io_tid;
162wire [7:0] st_data_access_e;
163reg [7:0] st_data_access_m;
164reg [7:0] st_data_access_b;
165reg [7:0] st_data_access_w;
166reg [2:0] tmp_tid;
167reg [5:0] tmp_tnum;
168
169reg [39:0] store_pa_m;
170reg [39:0] store_pa_b;
171reg [39:0] store_pa_w;
172
173wire [1:0] l1_way_select;
174wire [6:0] l1_index;
175wire [27:0] my_way;
176wire [27:0] way0;
177wire [27:0] way1;
178wire [27:0] way2;
179wire [27:0] way3;
180
181wire [3:0] evict_inv_e;
182reg [3:0] evict_inv_m;
183reg [3:0] evict_inv_b;
184reg [3:0] evict_inv_w;
185wire [2:0] evict_srcid_e;
186reg [2:0] evict_srcid_m;
187reg [2:0] evict_srcid_b;
188reg [2:0] evict_srcid_w;
189
190wire [8:0] pcx_req;
191reg [8:0] pcx_req_1;
192wire [129:0] pcx_data;
193
194wire perfmon;
195wire perfmon_g;
196reg perfmon_m;
197reg perfmon_b;
198reg perfmon_w;
199wire [2:0] perfmon_tid;
200wire [2:0] perfmon_tid_g;
201reg [2:0] perfmon_tid_m;
202reg [2:0] perfmon_tid_b;
203reg [2:0] perfmon_tid_w;
204wire [5:0] perfmon_tnum;
205wire [7:0] perfmon_mask;
206wire [7:0] perfmon_mask_g;
207reg [7:0] perfmon_mask_m;
208reg [7:0] perfmon_mask_b;
209reg [7:0] perfmon_mask_w;
210
211wire [7:0] bst_kill;
212reg [2:0] bst_kill_tid;
213reg [5:0] bst_kill_tnum;
214
215wire [7:0] stb_state0_m;
216wire [7:0] stb_state1_m;
217wire [7:0] stb_state2_m;
218wire [7:0] stb_state3_m;
219wire [7:0] stb_state4_m;
220wire [7:0] stb_state5_m;
221wire [7:0] stb_state6_m;
222wire [7:0] stb_state7_m;
223reg [7:0] stb_state0_b;
224reg [7:0] stb_state1_b;
225reg [7:0] stb_state2_b;
226reg [7:0] stb_state3_b;
227reg [7:0] stb_state4_b;
228reg [7:0] stb_state5_b;
229reg [7:0] stb_state6_b;
230reg [7:0] stb_state7_b;
231reg [7:0] stb_state0_w;
232reg [7:0] stb_state1_w;
233reg [7:0] stb_state2_w;
234reg [7:0] stb_state3_w;
235reg [7:0] stb_state4_w;
236reg [7:0] stb_state5_w;
237reg [7:0] stb_state6_w;
238reg [7:0] stb_state7_w;
239reg [7:0] stb_state;
240reg stb_last;
241
242// Copy of dtag
243reg [27:0] dta_way0 [127:0];
244reg [27:0] dta_way1 [127:0];
245reg [27:0] dta_way2 [127:0];
246reg [27:0] dta_way3 [127:0];
247
248//---------------------
249// Misc Signals
250wire [2:0] mycid;
251integer tstamp;
252integer junk;
253integer i;
254
255initial begin // {
256 ldf_tnum_w = 6'b0;
257 dsrc = 2'b0;
258 sta_tid = 3'b0;
259 sta_tnum = 6'b0;
260 for (i=0; i<=7; i=i+1) begin
261 sta_suppress[i] = 1'b0;
262 end
263
264end // }
265
266// for debug only - allows display in Debussy
267wire sta_suppress0;
268wire sta_suppress1;
269wire sta_suppress2;
270wire sta_suppress3;
271wire sta_suppress4;
272wire sta_suppress5;
273wire sta_suppress6;
274wire sta_suppress7;
275
276 assign sta_suppress0 = sta_suppress[0];
277 assign sta_suppress1 = sta_suppress[1];
278 assign sta_suppress2 = sta_suppress[2];
279 assign sta_suppress3 = sta_suppress[3];
280 assign sta_suppress4 = sta_suppress[4];
281 assign sta_suppress5 = sta_suppress[5];
282 assign sta_suppress6 = sta_suppress[6];
283 assign sta_suppress7 = sta_suppress[7];
284
285//----------------------------------------------------------
286//----------------------------------------------------------
287// DUT probes
288
289 assign mycid = 0;
290
291//---------------------
292// Load Issue
293
294 // If Load to IO ASIs, load issue should not be sent.
295 // In this case, asi_internal_w is asserted and will suppress load_w.
296
297 assign load_w = `SPC0.lsu.dcc.ld_inst_vld_w &
298 ~`PROBES0.asi_internal_w &
299 ~`SPC0.lsu.dcc.flush_w &
300 ~ldi_pf_w;
301
302 // ldxa to IO ASI are already suppressed since load_w will not assert.
303 // ldi_suppress is required to also suppress normal ld to IO ASI address range.
304 assign ldi_suppress = (ldi_pa_w[39:32] == `IO_ASI_ADDR);
305
306 assign ldi_tid_w = `SPC0.lsu.dcc.tid_w;
307 assign ldi_tnum_w = {mycid,ldi_tid_w};
308 assign ldi_size_b = `SPC0.lsu.dcc.ldst_sz_b; // 2 bits
309 assign ldi_atomic_b = `SPC0.lsu.dcc.atomic_b;
310 assign ldi_qld_b = `SPC0.lsu.dcc.quad_ldd_b;
311 assign ldi_ldbl_b = `SPC0.lsu.dcc_ldbl_b;
312 assign ldi_ldd_b = ldi_ldbl_b & !ldi_qld_b;
313 assign ldi_bld_b = `SPC0.lsu.dcc.dcc_blk_inst_b;
314 assign ldi_pf_b = `SPC0.lsu.dcc.pref_inst_b;
315
316 // pa, tid are same for LoadIssue and StoreIssue
317 assign ldi_pa_b = {`SPC0.lsu.tlb_pgnum[39:13],
318 `SPC0.lsu.lmd.lsu_va_b[12:0]};
319
320//---------------------
321// Load Fill
322
323 assign load_fill_e = `SPC0.lsu.dcc.ld_fill_e;
324 assign ldf_tid_e = `SPC0.lsu.cid.cid_tid;
325 assign ldf_pa_e = {`SPC0.lsu.lmd.lmd_fill_addr_e[39:3],3'b0};
326
327//---------------------
328// Store Issue
329
330 // blk_inst_w will suppress store_w for 1st of 9 cycles on block store.
331
332 // If Store to IO ASIs, store issue should not be sent.
333 // In this case, asi_internal_w is asserted and will suppress store_w.
334
335 assign unflushed_store_w = `SPC0.lsu.sbc.unflushed_store_w;
336
337 assign store_w = unflushed_store_w &
338 (~(`PROBES0.asi_internal_w | blk_inst_w) |
339 bst_in_prog_w);
340
341 assign atomic_b = `SPC0.lsu.dcc.atomic_b;
342 assign rmo_st_b = `SPC0.lsu.sbc_rmo_st_b;
343 assign blk_inst_b = `SPC0.lsu.dcc.dcc_blk_inst_b;
344
345 assign sti_tnum_w = {mycid,sti_tid_w};
346 assign sti_size_m = `SPC0.lsu.dcc_ldst_bmask;
347
348 // flip_size will assert if endian swap for partial store is needed
349 assign flip_size_b = `SPC0.lsu.dcc.pst_asi_b & `SPC0.lsu.dcc.tlb_tte_ie_b & `SPC0.lsu.dcc.tlb_tte_vld_b & `SPC0.lsu.dcc.st_inst_vld_b;
350
351 // Change itype only when control signals are valid
352 assign sti_itype_w = unflushed_store_w ? itype_w : sti_itype_w;
353
354 // It is correct to mix W & B stage signals for this.
355 // STD is a 2 cycle instruction.
356 // inst valid in W, data in B (1 cycle behind)
357 assign sti_data_w = `SPC0.lsu.sbc.std_inst_w ?
358 sbd_st_data_b :
359 sbd_st_data_w;
360 assign sbd_st_data_b = `SPC0.lsu.sbd_st_data_b;
361
362 // Use different pa,tid if block store
363 assign sti_pa_b = bst_in_prog_b ? bst_pa_b : st_pa_b;
364 assign sti_tid_b = bst_in_prog_b ? bst_tid_b : st_tid_b;
365
366 // stxa to IO ASI are already suppressed since store_w will not assert.
367 // sti_suppress is required to also suppress normal st to IO ASI address range.
368 assign sti_suppress = (sti_pa_w[39:32] == `IO_ASI_ADDR);
369
370 // Normal Store
371 assign st_pa_b = {`SPC0.lsu.tlb_pgnum[39:13],
372 `SPC0.lsu.lmd.lsu_va_b[12:0]};
373 assign st_tid_b = `SPC0.lsu.dcc.tid_b;
374
375 // Block Store
376 assign bst_in_prog_b = `SPC0.lsu.sbc.bst_in_prog_b;
377 assign bst_pa_b = {`SPC0.lsu.sbd.st_addr_b[39:3],3'b0};
378 assign bst_tid_b = `SPC0.lsu.sbc.bst_tid;
379
380//---------------------
381// Store Ack
382
383assign asi_st_dequeue[7:0] = `SPC0.lsu.dcc_asi_rtn_vld[7:0] &
384 {8{~`SPC0.lsu.dcc_asi_rtn_rd}};
385
386 assign st_ack_no_asi_e = `SPC0.lsu.cic.cic_st_dequeue[7:0] &
387 ~asi_st_dequeue[7:0] &
388 ~`SPC0.lsu.cic.sbc_bst_sel[7:0];
389
390 assign st_ack_rmo_b = {`SPC0.lsu.sbs7.rmo_st_commit_p4,
391 `SPC0.lsu.sbs6.rmo_st_commit_p4,
392 `SPC0.lsu.sbs5.rmo_st_commit_p4,
393 `SPC0.lsu.sbs4.rmo_st_commit_p4,
394 `SPC0.lsu.sbs3.rmo_st_commit_p4,
395 `SPC0.lsu.sbs2.rmo_st_commit_p4,
396 `SPC0.lsu.sbs1.rmo_st_commit_p4,
397 `SPC0.lsu.sbs0.rmo_st_commit_p4
398 };
399
400 // It is possible to see 2 threads store_ack in same cycle
401 // (1 st_ack_no_asi & 1 st_ack_rmo)
402
403 assign store_ack_b = st_ack_no_asi_b | st_ack_rmo_b;
404
405 // cic_st_atm_cmplt is atomic store completing (same time as store ack)
406 // (lsu.lmc.dcl2u_err | dcl2nd_err) indicate a data_access_error condition
407 assign st_data_access_e = {8{(`SPC0.lsu.cic.cic_st_atm_cmplt &
408 (`SPC0.lsu.lmc.dcl2u_err | `SPC0.lsu.lmc.dcl2nd_err))}} &
409 `SPC0.lsu.cic.cic_st_dequeue[7:0];
410//---------------------
411// Store Inv
412
413 // Same as evict_inv_e but with cpq_evict deasserted
414 assign store_inv_e = `SPC0.lsu.cic_invalidate_e &
415 (`SPC0.lsu.cic_inv_wen_e!=0)&
416 ~`SPC0.lsu.cic.cpq_evict &
417 ~`SPC0.lsu.cic.cid_set_inval &
418 ~`SPC0.lsu.cic.cic_xinval_e &
419 ~(`SPC0.lsu.cic.cid_pkt_type[4:0] == 5'b10110);
420 assign stinv_tnum_e =
421 {`SPC0.lsu.cid.cpq_data_out[`CPX_VACK_CID],
422 `SPC0.lsu.cid.cid_tid};
423
424//---------------------
425// Store Update
426
427 assign store_update_e = `SPC0.lsu.cic_st_update_e;
428 assign stu_tid_e = `SPC0.lsu.cid.cid_tid;
429 assign stu_tnum_e = {mycid,stu_tid_e};
430
431 assign l1_index = {`SPC0.lsu.cid.cpq_data_out[116],
432 `SPC0.lsu.cid.cpq_data_out[115],
433 `SPC0.lsu.cid.cpq_data_out[114],
434 `SPC0.lsu.cid.cpq_data_out[113],
435 `SPC0.lsu.cid.cpq_data_out[112],
436 `SPC0.lsu.cid.cpq_data_out[122],
437 `SPC0.lsu.cid.cpq_data_out[121]
438 };
439 assign l1_way_select = `SPC0.lsu.cid_inv_vec[17:16];
440
441//---------------------
442// EvictInv
443
444 // Same as store_inv_e but with cpq_evict asserted
445 // LSU can invalidate 1-4 Dcache lines
446 assign evict_inv_e[3:0] = {4{`SPC0.lsu.cic_invalidate_e & // enable for 4 bit wen below
447 (`SPC0.lsu.cic_inv_wen_e!=0)&
448 `SPC0.lsu.cic.cpq_evict &
449 ~`SPC0.lsu.cic.cid_set_inval &
450 ~`SPC0.lsu.cic.cic_xinval_e}} &
451
452 {|(`SPC0.lsu.cic.evict_inv_wen[15:12]), // 4 bit field - 1 hot. Send evinv when any one set.
453 |(`SPC0.lsu.cic.evict_inv_wen[11:8]),
454 |(`SPC0.lsu.cic.evict_inv_wen[7:4]),
455 |(`SPC0.lsu.cic.evict_inv_wen[3:0])
456 };
457
458 assign evict_srcid_e = `SPC0.lsu.cid.cpq_data_out[114:112];
459
460
461//---------------------
462// Detect Store to IO ASI in PCX crossbar packet.
463// This causes next Store Ack to be suppressed.
464
465// Normal Store only since atomics are always to cacheable space
466
467// Trigger on Store to crossbar.
468// If Store request is retried on crossbar (due to no grant),
469// then, st_io_asi will fire multiple times for the same request.
470// This is OK because it just causes sta_suppress to be set multiple times.
471
472 assign pcx_req = `SPC0.spc_pcx_req_pq;
473 assign pcx_data = `SPC0.spc_pcx_data_pa;
474
475 assign st_io_asi = (pcx_req_1 != 9'b0) &
476 (pcx_data [`PCX_VALID]==1'b1) &
477 (pcx_data [`PCX_RQTYP]==`CCX_REQ_ST) &
478 (pcx_data [103:96]==`IO_ASI_ADDR); // Upper byte of 40 bit addr
479
480 assign st_io_tid = pcx_data [`PCX_TID];
481
482 assign stb_state0_m = `SPC0.lsu.sbs0.stb_state_vld[7:0];
483 assign stb_state1_m = `SPC0.lsu.sbs1.stb_state_vld[7:0];
484 assign stb_state2_m = `SPC0.lsu.sbs2.stb_state_vld[7:0];
485 assign stb_state3_m = `SPC0.lsu.sbs3.stb_state_vld[7:0];
486 assign stb_state4_m = `SPC0.lsu.sbs4.stb_state_vld[7:0];
487 assign stb_state5_m = `SPC0.lsu.sbs5.stb_state_vld[7:0];
488 assign stb_state6_m = `SPC0.lsu.sbs6.stb_state_vld[7:0];
489 assign stb_state7_m = `SPC0.lsu.sbs7.stb_state_vld[7:0];
490
491//---------------------
492// Load Data (hit only) (See ldst_l2.v for Load Data - miss)
493
494 assign load_data_hit = load_w && (hit_w | fraw_w);
495 assign ld_miss_b = `SPC0.lsu.dcc.dcc_ld_miss_b;
496 assign fraw_w = `SPC0.lsu.lmc.ld_raw_bypass_w;
497 assign hit_w = ~ld_miss_w & ~stb_hit_w;
498 assign miss_w = ~fraw_w & (ld_miss_w | stb_hit_w);
499
500//---------------------
501// Load Pop
502
503 assign perfmon_g = `SPC0.lsu.lsu_perfmon_trap_g;
504 assign perfmon_tid_g = `SPC0.lsu.lsu_dcerr_tid_g;
505 // perfmon_mask will not fire if trap is not enabled or higher priority trap is taken.
506 assign perfmon_mask_g = {`SPC0.tlu.fls1.pil_mask_15[3:0], `SPC0.tlu.fls0.pil_mask_15[3:0]} &
507 ~{8 {`SPC0.lsu_dcl2u_err_g | `SPC0.lsu_dcl2nd_err_g}};
508
509 assign perfmon = perfmon_w;
510 assign perfmon_tid = perfmon_tid_w;
511 assign perfmon_tnum = {mycid,perfmon_tid_w};
512 assign perfmon_mask = perfmon_mask_w;
513
514
515
516//---------------------
517// Store Pop
518
519 assign bst_kill = {`SPC0.lsu.sbs7.bst_kill,
520 `SPC0.lsu.sbs6.bst_kill,
521 `SPC0.lsu.sbs5.bst_kill,
522 `SPC0.lsu.sbs4.bst_kill,
523 `SPC0.lsu.sbs3.bst_kill,
524 `SPC0.lsu.sbs2.bst_kill,
525 `SPC0.lsu.sbs1.bst_kill,
526 `SPC0.lsu.sbs0.bst_kill};
527
528//----------------------------------------------------------
529//----------------------------------------------------------
530
531always @ (posedge `SPC0.l2clk) begin // {
532
533 tstamp = `TOP.core_cycle_cnt - 1;
534
535 //------------------------------
536 // Pipeline from B to W
537
538 ldi_pa_w <= ldi_pa_b;
539 ld_miss_w <= ld_miss_b;
540 stb_hit_w <= `SPC0.lsu.stb_cam_hit;
541 ldi_pf_w <= ldi_pf_b;
542 ldi_size_w <= ldi_size_b;
543 load_fill_m <= load_fill_e;
544 load_fill_b <= load_fill_m;
545 load_fill_w <= load_fill_b;
546 ldf_tid_m <= ldf_tid_e;
547 ldf_tid_b <= ldf_tid_m;
548 ldf_tid_w <= ldf_tid_b;
549 ldf_pa_m <= ldf_pa_e;
550 ldf_pa_b <= ldf_pa_m;
551 ldf_pa_w <= ldf_pa_b;
552
553 sti_size_b <= sti_size_m;
554 sti_size_w <= (flip_size_b) ? {sti_size_b[0],sti_size_b[1],sti_size_b[2],sti_size_b[3],
555 sti_size_b[4],sti_size_b[5],sti_size_b[6],sti_size_b[7]}
556 : sti_size_b;
557 sti_pa_w <= sti_pa_b;
558 sti_tid_w <= sti_tid_b;
559 st_ack_no_asi_m <= st_ack_no_asi_e;
560 st_ack_no_asi_b <= st_ack_no_asi_m;
561 st_data_access_m <= st_data_access_e;
562 st_data_access_b <= st_data_access_m;
563 st_data_access_w <= st_data_access_b;
564 store_ack_w <= store_ack_b;
565 store_update_m <= store_update_e;
566 store_update_b <= store_update_m;
567 store_update_w <= store_update_b;
568 store_inv_m <= store_inv_e;
569 store_inv_b <= store_inv_m;
570 store_inv_w <= store_inv_b;
571 stinv_tnum_m <= stinv_tnum_e;
572 stinv_tnum_b <= stinv_tnum_m;
573 stinv_tnum_w <= stinv_tnum_b;
574 st_ack_rmo_w <= st_ack_rmo_b;
575 stu_tid_m <= stu_tid_e;
576 stu_tid_b <= stu_tid_m;
577 stu_tid_w <= stu_tid_b;
578 stu_tnum_m <= stu_tnum_e;
579 stu_tnum_b <= stu_tnum_m;
580 stu_tnum_w <= stu_tnum_b;
581 store_pa_b <= store_pa_m;
582 store_pa_w <= store_pa_b;
583 bst_in_prog_w <= bst_in_prog_b;
584 blk_inst_w <= blk_inst_b;
585 sbd_st_data_w <= sbd_st_data_b;
586 evict_inv_m <= evict_inv_e;
587 evict_inv_b <= evict_inv_m;
588 evict_inv_w <= evict_inv_b;
589 evict_srcid_m <= evict_srcid_e;
590 evict_srcid_b <= evict_srcid_m;
591 evict_srcid_w <= evict_srcid_b;
592 pcx_req_1 <= pcx_req;
593 stb_state0_b <= stb_state0_m;
594 stb_state1_b <= stb_state1_m;
595 stb_state2_b <= stb_state2_m;
596 stb_state3_b <= stb_state3_m;
597 stb_state4_b <= stb_state4_m;
598 stb_state5_b <= stb_state5_m;
599 stb_state6_b <= stb_state6_m;
600 stb_state7_b <= stb_state7_m;
601 stb_state0_w <= stb_state0_b;
602 stb_state1_w <= stb_state1_b;
603 stb_state2_w <= stb_state2_b;
604 stb_state3_w <= stb_state3_b;
605 stb_state4_w <= stb_state4_b;
606 stb_state5_w <= stb_state5_b;
607 stb_state6_w <= stb_state6_b;
608 stb_state7_w <= stb_state7_b;
609
610 perfmon_m <= perfmon_g;
611 perfmon_b <= perfmon_m;
612 perfmon_w <= perfmon_b;
613 perfmon_tid_m <= perfmon_tid_g;
614 perfmon_tid_b <= perfmon_tid_m;
615 perfmon_tid_w <= perfmon_tid_b;
616 perfmon_mask_m <= perfmon_mask_g;
617 perfmon_mask_b <= perfmon_mask_m;
618 perfmon_mask_w <= perfmon_mask_b;
619
620 //----------------------------------------------------------
621 // Calculate pa for STUPDATE and STINV
622 // Moved this into the always block to avoid the constant
623 // probing of the dtag memory structure.
624
625 if (store_inv_e | store_update_e) begin // {
626 store_pa_m[2:0] <= 3'b000;
627 store_pa_m[10:3] <= {`SPC0.lsu.cid.cpq_data_out[116],
628 `SPC0.lsu.cid.cpq_data_out[115],
629 `SPC0.lsu.cid.cpq_data_out[114],
630 `SPC0.lsu.cid.cpq_data_out[113],
631 `SPC0.lsu.cid.cpq_data_out[112],
632 `SPC0.lsu.cid.cpq_data_out[122],
633 `SPC0.lsu.cid.cpq_data_out[121],
634 `SPC0.lsu.cid.cpq_data_out[104]
635 };
636 store_pa_m[38:11] <= (l1_way_select==2'h0) ? dta_way0[l1_index] :
637 (l1_way_select==2'h1) ? dta_way1[l1_index] :
638 (l1_way_select==2'h2) ? dta_way2[l1_index] : dta_way3[l1_index];
639 store_pa_m[39] <= 1'b0; // Only memory stores get inv/update
640 end // }
641
642
643 // After Store to IO ASI is detected at StI time, suppress the next Store Ack
644 // There is only 1 store to IO ASI active at one time per thread because
645 // that is all the LSU allows.
646 if (st_io_asi) begin
647 sta_suppress [st_io_tid] <= 1'b1;
648 end
649
650 case ({ldi_atomic_b,ldi_bld_b,ldi_ldd_b,ldi_qld_b,ldi_pf_b})
651 5'b00000: ldi_itype_w <= `ITYPE_LOAD;
652 5'b00001: ldi_itype_w <= `ITYPE_PREFETCH;
653 5'b00010: ldi_itype_w <= `ITYPE_QUAD_LOAD;
654 5'b00100: ldi_itype_w <= `ITYPE_DOUBLE_LOAD;
655 5'b01000: ldi_itype_w <= `ITYPE_BLOCK_LOAD;
656 5'b10000: ldi_itype_w <= `ITYPE_ATOMIC;
657 default: ldi_itype_w <= `ITYPE_NO; // Illegal
658 endcase
659
660 case ({atomic_b,rmo_st_b,bst_in_prog_b})
661 3'b000: itype_w <= `ITYPE_STORE;
662 3'b010: itype_w <= `ITYPE_BLK_INIT_ST;
663 3'b011: itype_w <= `ITYPE_BLOCK_STORE;
664 3'b100: itype_w <= `ITYPE_ATOMIC;
665 3'b001,
666 3'b101,
667 3'b110,
668 3'b111: itype_w <= `ITYPE_NO; // Illegal
669 endcase
670
671 //----------------------------------------------------------
672 //----------------------------------------------------------
673 // Load Issue
674
675 // Load Issue must be before Store Issue for atomic
676
677 if (load_w) begin // {
678
679 if (ldi_suppress==1'b0) begin // {
680 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
681 `PR_INFO ("pli_ldst", `INFO,
682 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h size=%h typ=%0h ts=%0d",
683 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
684 junk = $sim_send(`PLI_MEM_LD_ISSUE,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
685 end // }
686 end // }
687 else begin // {
688 `PR_INFO ("pli_ldst", `INFO,
689 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h Suppress for IO ASI",mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w);
690 end // }
691
692 if (`PARGS.show_memop_on) begin // {
693 `PR_NORMAL ("pli_ldst", `NORMAL,
694 "C%0d T%0d MEMOP_LOAD tid=%d pa=%h ts=%0d (LSU - W stage)",
695 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,tstamp);
696 end // }
697
698 end // }
699
700 //----------------------------------------------------------
701 //----------------------------------------------------------
702 // Load Data (hit only) (See ldst_l2.v for Load Data - miss)
703
704 if (load_data_hit) begin // {
705
706 dsrc = hit_w ? `DSRC_L1 : `DSRC_STB;
707
708 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
709 `PR_INFO ("pli_ldst", `INFO,
710 "C%0d T%0d PLI_MEM_LDDATA tid=%d pa=%h dsrc=%0h ts=%0d",
711 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
712 junk = $sim_send(`PLI_MEM_LD_DATA,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
713 end // }
714
715 end // }
716
717
718 //----------------------------------------------------------
719 //----------------------------------------------------------
720 // Store Ack
721 //
722 // Store Ack cmd must be sent before Store Inv, Store Update for NAS
723 // Store Ack & Store Update will be in the same timestamp
724
725 if (store_ack_w != 8'b0) begin // {
726
727 for (i=0; i<=7; i=i+1) begin // {
728 if (store_ack_w[i]) begin // {
729 sta_tid = i[2:0];
730 sta_tnum = {mycid,sta_tid};
731 sta_rmo = st_ack_rmo_w[i];
732
733 if (sta_suppress[sta_tid]==1'b0) begin // {
734 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
735 `PR_INFO ("pli_ldst", `INFO,
736 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
737 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
738 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
739 end // }
740 end // }
741
742 else begin // {
743
744 // It is possible for 2 Stores it be in flight because of the delay from CPQ push & pop.
745 // So, make sure Bench is suppressing the correct Store.
746 case (sta_tid)
747 3'h0: stb_state=stb_state0_w;
748 3'h1: stb_state=stb_state1_w;
749 3'h2: stb_state=stb_state2_w;
750 3'h3: stb_state=stb_state3_w;
751 3'h4: stb_state=stb_state4_w;
752 3'h5: stb_state=stb_state5_w;
753 3'h6: stb_state=stb_state6_w;
754 3'h7: stb_state=stb_state7_w;
755 default:
756 `PR_ERROR ("pli_ldst", `ERROR,
757 "C%0d T%0d PLI_MEM_XXX Bench Error. Should never execute case default",mycid,sta_tid);
758 endcase
759
760 // If stb_state has only 1 bit asserted, then suppress the STACK. Otherwise, send the STACK.
761 case (stb_state) // {
762 8'b0000_0000: begin
763 `PR_ERROR ("pli_ldst", `ERROR,
764 "C%0d T%0d PLI_MEM_XXX Bench Error. stb_state should not be 8'b0",
765 mycid,sta_tid);
766 end
767 8'b0000_0001,
768 8'b0000_0010,
769 8'b0000_0100,
770 8'b0000_1000,
771 8'b0001_0000,
772 8'b0010_0000,
773 8'b0100_0000,
774 8'b1000_0000: stb_last = 1'b1;
775 default: stb_last = 1'b0;
776 endcase // }
777
778 if (stb_last==1'b0) begin // {
779 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
780 `PR_INFO ("pli_ldst", `INFO,
781 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
782 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
783 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
784 end // }
785 end // }
786 else begin // {
787 sta_suppress[sta_tid] <= 1'b0;
788 `PR_INFO ("pli_ldst", `INFO,
789 "C%0d T%0d PLI_MEM_STACK tid=%d Suppress for IO ASI",mycid,sta_tid,sta_tnum);
790 end // }
791 end // }
792
793 end // if (store_ack_w[i]) }
794 end // for }
795
796 end // if (store_ack_w) }
797
798 //----------------------------------------------------------
799 //----------------------------------------------------------
800 // Store Inv
801
802 if (store_inv_w) begin // {
803
804 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stinv_tnum_w]) begin // {
805 `PR_INFO ("pli_ldst", `INFO,
806 "C%0d PLI_MEM_STINV tid=%d pa=%h cid=%h ts=%0d",
807 mycid,stinv_tnum_w,store_pa_w,mycid,tstamp);
808 junk = $sim_send(`PLI_MEM_ST_INV,mycid,stinv_tnum_w,store_pa_w,tstamp);
809 end // }
810
811 end // }
812
813
814 //----------------------------------------------------------
815 //----------------------------------------------------------
816 // Store Update
817
818 if (store_update_w) begin // {
819
820 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stu_tnum_w]) begin // {
821 `PR_INFO ("pli_ldst", `INFO,
822 "C%0d T%0d PLI_MEM_STUP tid=%d pa=%h ts=%0d",
823 mycid,stu_tid_w,stu_tnum_w,store_pa_w,tstamp);
824 junk = $sim_send(`PLI_MEM_ST_UPDATE,stu_tnum_w,store_pa_w,tstamp);
825 end // }
826
827 end // }
828
829 //----------------------------------------------------------
830 //----------------------------------------------------------
831 // Load Fill
832
833 if (load_fill_w) begin // {
834
835 ldf_tnum_w = {mycid,ldf_tid_w};
836
837 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldf_tnum_w]) begin // {
838 `PR_INFO ("pli_ldst", `INFO,
839 "C%0d T%0d PLI_MEM_LDFILL tid=%d pa=%h ts=%0d",
840 mycid,ldf_tid_w,ldf_tnum_w,ldf_pa_w,tstamp);
841 junk = $sim_send(`PLI_MEM_LD_FILL,ldf_tnum_w,ldf_pa_w,tstamp);
842 end // }
843
844 end // }
845
846 //----------------------------------------------------------
847 //----------------------------------------------------------
848 // Store Issue
849
850 if (store_w) begin // {
851
852 if (sti_suppress==1'b0) begin // {
853 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sti_tnum_w]) begin // {
854 `PR_INFO ("pli_ldst", `INFO,
855 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h data=%h sz=%h typ=%0h ts=%0d",
856 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
857 junk = $sim_send(`PLI_MEM_ST_ISSUE,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
858 end // }
859
860 end // }
861 else begin // {
862 `PR_INFO ("pli_ldst", `INFO,
863 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h Suppress for IO ASI",mycid,sti_tid_w,sti_tnum_w,sti_pa_w);
864 end // }
865
866 if (`PARGS.show_memop_on) begin // {
867 `PR_NORMAL ("pli_ldst", `NORMAL,
868 "C%0d T%0d MEMOP_STORE tid=%d pa=%h data=%h sz=%h ts=%0d (LSU - W stage)",
869 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,tstamp);
870 end // }
871
872 end // }
873
874 //----------------------------------------------------------
875 //----------------------------------------------------------
876 // EvictInv
877 // Send 1-4 EvictInv messages per cycle - based on how many Dcache lines were invalidated.
878
879 for (i=0; i<=3; i=i+1) begin // {
880 if (evict_inv_w[i]) begin // {
881
882 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on) begin // {
883 `PR_INFO ("pli_ldst", `INFO,
884 "C%0d PLI_MEM_EVINV cid=%d srcid=%0d ts=%0d",
885 mycid,mycid,evict_srcid_w,tstamp);
886 junk = $sim_send(`PLI_MEM_EVICT_INV,mycid,evict_srcid_w,tstamp);
887 end // }
888
889 end // }
890 end // }
891
892 //----------------------------------------------------------
893 //----------------------------------------------------------
894 // Load Pop - special case
895
896 // This is required in case of a performance monitor trap due to L2 miss.
897 // In this case, the trap is not indicated until after the Load pkt returns to the LSU.
898 // ldst_sync has already sent LDISSUE and LDDATA to Riesling. But, the Load is not executed.
899 // Load Pop tells Riesling to pop the LDISSUE,LDDATA off of its queues.
900
901 if (perfmon & perfmon_mask[perfmon_tid]) begin // {
902
903 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[perfmon_tnum]) begin // {
904 `PR_INFO ("pli_ldst", `INFO,
905 "C%0d T%0d PLI_MEM_LDPOP tid=%d ts=%0d",
906 mycid,perfmon_tid,perfmon_tnum,tstamp);
907 junk = $sim_send(`PLI_MEM_LD_POP,perfmon_tnum);
908 end // }
909
910 end // }
911
912 //----------------------------------------------------------
913 //----------------------------------------------------------
914 // Store Pop - special cases
915
916 // This is required in case of a FRF error trap (internal_proc_error) on a Block Store.
917 // In this case, the trap is not indicated until after the 8 STISSUE has been sent to Riesling.
918 // But, the Store is not executed.
919 // Store Pop tells Riesling to pop the 8 STISSUE off of its queues.
920
921 if (bst_kill!==8'b0) begin // {
922
923 for (i=0;i<=7;i=i+1) begin
924 if (bst_kill[i]==1'b1) begin
925 bst_kill_tid = i;
926 bst_kill_tnum = {mycid,bst_kill_tid};
927
928 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[bst_kill_tnum]) begin // {
929 `PR_INFO ("pli_ldst", `INFO,
930 "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
931 mycid,bst_kill_tid,bst_kill_tnum,tstamp);
932 junk = $sim_send(`PLI_MEM_ST_POP,bst_kill_tnum);
933 end // }
934 end
935 end
936
937 end // }
938
939 //--------------------
940 // This is required for data_access_error on atomic. In this case, Riesling only cleans up the Load,
941 // but doesn't know it is an atomic so Riesling doesn't clean up the store in its buffers.
942 // The STPOP tells Riesling to clear the newest Store from the buffers.
943 // It is possible to have older Stores in-flight but not newer Stores in-flight.
944
945// if (st_data_access_w != 8'b0) begin // {
946//
947// for (i=0; i<=7; i=i+1) begin // {
948// if (st_data_access_w[i]) begin // {
949// tmp_tid = i[2:0];
950// tmp_tnum = {mycid,tmp_tid};
951//
952// if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[tmp_tnum]) begin // {
953// `PR_INFO ("pli_ldst", `INFO,
954// "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
955// mycid,tmp_tid,tmp_tnum,tstamp);
956// junk = $sim_send(`PLI_MEM_ST_POP,tmp_tnum);
957// end // }
958// end // } if st_data_access[i]
959// end // } for
960// end // } if st_data_access
961
962end // always }
963
964//----------------------------------------------------------
965// Need to model the D arrays to get PA's for store updates and invalidates
966
967always @ (negedge `SPC0.l2clk) begin // {
968 if (`SPC0.lsu.dta.wr_way[0])
969 dta_way0[`SPC0.lsu.dta.index_y[6:0]] <= `SPC0.lsu.dta.wrtag_y[27:0];
970 if (`SPC0.lsu.dta.wr_way[1])
971 dta_way1[`SPC0.lsu.dta.index_y[6:0]] <= `SPC0.lsu.dta.wrtag_y[27:0];
972 if (`SPC0.lsu.dta.wr_way[2])
973 dta_way2[`SPC0.lsu.dta.index_y[6:0]] <= `SPC0.lsu.dta.wrtag_y[27:0];
974 if (`SPC0.lsu.dta.wr_way[3])
975 dta_way3[`SPC0.lsu.dta.index_y[6:0]] <= `SPC0.lsu.dta.wrtag_y[27:0];
976end // always }
977
978//----------------------------------------------------------
979`endif
980endmodule
981
982`endif
983`ifdef CORE_1
984
985module ldst_lsu_c1 ();
986`ifndef GATESIM
987
988// common defines
989`include "defines.vh"
990`include "nas.vh"
991// PCX/CPX packet defines (see :/verif/env/common/vera/include)
992`include "ccx.vri"
993`include "cmp.vri"
994
995//---------------------
996// Load Signals
997wire load_w;
998
999wire ldi_suppress;
1000wire [2:0] ldi_tid_w;
1001wire [5:0] ldi_tnum_w;
1002wire [39:0] ldi_pa_b;
1003reg [39:0] ldi_pa_w;
1004wire [1:0] ldi_size_b;
1005reg [1:0] ldi_size_w;
1006wire ldi_bld_b;
1007wire ldi_qld_b;
1008wire ldi_ldbl_b;
1009wire ldi_ldd_b;
1010wire ldi_atomic_b;
1011wire ldi_pf_b;
1012reg ldi_pf_w;
1013reg [7:0] ldi_itype_w;
1014reg [7:0] dsrc;
1015
1016wire ld_miss_b;
1017reg ld_miss_w;
1018reg stb_hit_w;
1019wire fraw_w;
1020wire hit_w;
1021wire miss_w;
1022wire load_data_hit;
1023
1024wire load_fill_e;
1025reg load_fill_m;
1026reg load_fill_b;
1027reg load_fill_w;
1028wire [2:0] ldf_tid_e;
1029reg [2:0] ldf_tid_m;
1030reg [2:0] ldf_tid_b;
1031reg [2:0] ldf_tid_w;
1032reg [5:0] ldf_tnum_w;
1033wire [39:0] ldf_pa_e;
1034reg [39:0] ldf_pa_m;
1035reg [39:0] ldf_pa_b;
1036reg [39:0] ldf_pa_w;
1037
1038//---------------------
1039// Store Signals
1040wire unflushed_store_w;
1041wire store_w;
1042wire sti_suppress;
1043wire [2:0] sti_tid_b;
1044reg [2:0] sti_tid_w;
1045wire [5:0] sti_tnum_w;
1046wire [39:0] sti_pa_b;
1047reg [39:0] sti_pa_w;
1048wire [63:0] sti_data_w;
1049wire [7:0] sti_size_m;
1050reg [7:0] sti_size_b;
1051reg [7:0] sti_size_w;
1052wire [7:0] sti_itype_w;
1053reg [7:0] itype_w;
1054wire [63:0] sbd_st_data_b;
1055reg [63:0] sbd_st_data_w;
1056wire flip_size_b;
1057
1058wire atomic_b;
1059wire rmo_st_b;
1060wire blk_inst_b;
1061reg blk_inst_w;
1062
1063wire bst_in_prog_b;
1064reg bst_in_prog_w;
1065wire [39:0] bst_pa_b;
1066reg [39:0] bst_pa_w;
1067wire [2:0] bst_tid_b;
1068reg [2:0] bst_tid_w;
1069wire [39:0] st_pa_b;
1070reg [39:0] st_pa_w;
1071wire [2:0] st_tid_b;
1072reg [2:0] st_tid_w;
1073
1074wire store_inv_e;
1075reg store_inv_m;
1076reg store_inv_b;
1077reg store_inv_w;
1078wire [5:0] stinv_tnum_e;
1079reg [5:0] stinv_tnum_m;
1080reg [5:0] stinv_tnum_b;
1081reg [5:0] stinv_tnum_w;
1082
1083wire store_update_e;
1084reg store_update_m;
1085reg store_update_b;
1086reg store_update_w;
1087wire [2:0] stu_tid_e;
1088reg [2:0] stu_tid_m;
1089reg [2:0] stu_tid_b;
1090reg [2:0] stu_tid_w;
1091wire [5:0] stu_tnum_e;
1092reg [5:0] stu_tnum_m;
1093reg [5:0] stu_tnum_b;
1094reg [5:0] stu_tnum_w;
1095
1096wire [7:0] asi_st_dequeue;
1097wire [7:0] st_ack_no_asi_e;
1098reg [7:0] st_ack_no_asi_m;
1099reg [7:0] st_ack_no_asi_b;
1100wire [7:0] store_ack_b;
1101reg [7:0] store_ack_w;
1102wire [7:0] st_ack_rmo_b;
1103reg [7:0] st_ack_rmo_w;
1104reg sta_rmo;
1105reg [2:0] sta_tid;
1106reg [5:0] sta_tnum;
1107reg sta_suppress [0:7]; // 1 per thread
1108wire st_io_asi;
1109wire [2:0] st_io_tid;
1110wire [7:0] st_data_access_e;
1111reg [7:0] st_data_access_m;
1112reg [7:0] st_data_access_b;
1113reg [7:0] st_data_access_w;
1114reg [2:0] tmp_tid;
1115reg [5:0] tmp_tnum;
1116
1117reg [39:0] store_pa_m;
1118reg [39:0] store_pa_b;
1119reg [39:0] store_pa_w;
1120
1121wire [1:0] l1_way_select;
1122wire [6:0] l1_index;
1123wire [27:0] my_way;
1124wire [27:0] way0;
1125wire [27:0] way1;
1126wire [27:0] way2;
1127wire [27:0] way3;
1128
1129wire [3:0] evict_inv_e;
1130reg [3:0] evict_inv_m;
1131reg [3:0] evict_inv_b;
1132reg [3:0] evict_inv_w;
1133wire [2:0] evict_srcid_e;
1134reg [2:0] evict_srcid_m;
1135reg [2:0] evict_srcid_b;
1136reg [2:0] evict_srcid_w;
1137
1138wire [8:0] pcx_req;
1139reg [8:0] pcx_req_1;
1140wire [129:0] pcx_data;
1141
1142wire perfmon;
1143wire perfmon_g;
1144reg perfmon_m;
1145reg perfmon_b;
1146reg perfmon_w;
1147wire [2:0] perfmon_tid;
1148wire [2:0] perfmon_tid_g;
1149reg [2:0] perfmon_tid_m;
1150reg [2:0] perfmon_tid_b;
1151reg [2:0] perfmon_tid_w;
1152wire [5:0] perfmon_tnum;
1153wire [7:0] perfmon_mask;
1154wire [7:0] perfmon_mask_g;
1155reg [7:0] perfmon_mask_m;
1156reg [7:0] perfmon_mask_b;
1157reg [7:0] perfmon_mask_w;
1158
1159wire [7:0] bst_kill;
1160reg [2:0] bst_kill_tid;
1161reg [5:0] bst_kill_tnum;
1162
1163wire [7:0] stb_state0_m;
1164wire [7:0] stb_state1_m;
1165wire [7:0] stb_state2_m;
1166wire [7:0] stb_state3_m;
1167wire [7:0] stb_state4_m;
1168wire [7:0] stb_state5_m;
1169wire [7:0] stb_state6_m;
1170wire [7:0] stb_state7_m;
1171reg [7:0] stb_state0_b;
1172reg [7:0] stb_state1_b;
1173reg [7:0] stb_state2_b;
1174reg [7:0] stb_state3_b;
1175reg [7:0] stb_state4_b;
1176reg [7:0] stb_state5_b;
1177reg [7:0] stb_state6_b;
1178reg [7:0] stb_state7_b;
1179reg [7:0] stb_state0_w;
1180reg [7:0] stb_state1_w;
1181reg [7:0] stb_state2_w;
1182reg [7:0] stb_state3_w;
1183reg [7:0] stb_state4_w;
1184reg [7:0] stb_state5_w;
1185reg [7:0] stb_state6_w;
1186reg [7:0] stb_state7_w;
1187reg [7:0] stb_state;
1188reg stb_last;
1189
1190// Copy of dtag
1191reg [27:0] dta_way0 [127:0];
1192reg [27:0] dta_way1 [127:0];
1193reg [27:0] dta_way2 [127:0];
1194reg [27:0] dta_way3 [127:0];
1195
1196//---------------------
1197// Misc Signals
1198wire [2:0] mycid;
1199integer tstamp;
1200integer junk;
1201integer i;
1202
1203initial begin // {
1204 ldf_tnum_w = 6'b0;
1205 dsrc = 2'b0;
1206 sta_tid = 3'b0;
1207 sta_tnum = 6'b0;
1208 for (i=0; i<=7; i=i+1) begin
1209 sta_suppress[i] = 1'b0;
1210 end
1211
1212end // }
1213
1214// for debug only - allows display in Debussy
1215wire sta_suppress0;
1216wire sta_suppress1;
1217wire sta_suppress2;
1218wire sta_suppress3;
1219wire sta_suppress4;
1220wire sta_suppress5;
1221wire sta_suppress6;
1222wire sta_suppress7;
1223
1224 assign sta_suppress0 = sta_suppress[0];
1225 assign sta_suppress1 = sta_suppress[1];
1226 assign sta_suppress2 = sta_suppress[2];
1227 assign sta_suppress3 = sta_suppress[3];
1228 assign sta_suppress4 = sta_suppress[4];
1229 assign sta_suppress5 = sta_suppress[5];
1230 assign sta_suppress6 = sta_suppress[6];
1231 assign sta_suppress7 = sta_suppress[7];
1232
1233//----------------------------------------------------------
1234//----------------------------------------------------------
1235// DUT probes
1236
1237 assign mycid = 1;
1238
1239//---------------------
1240// Load Issue
1241
1242 // If Load to IO ASIs, load issue should not be sent.
1243 // In this case, asi_internal_w is asserted and will suppress load_w.
1244
1245 assign load_w = `SPC1.lsu.dcc.ld_inst_vld_w &
1246 ~`PROBES1.asi_internal_w &
1247 ~`SPC1.lsu.dcc.flush_w &
1248 ~ldi_pf_w;
1249
1250 // ldxa to IO ASI are already suppressed since load_w will not assert.
1251 // ldi_suppress is required to also suppress normal ld to IO ASI address range.
1252 assign ldi_suppress = (ldi_pa_w[39:32] == `IO_ASI_ADDR);
1253
1254 assign ldi_tid_w = `SPC1.lsu.dcc.tid_w;
1255 assign ldi_tnum_w = {mycid,ldi_tid_w};
1256 assign ldi_size_b = `SPC1.lsu.dcc.ldst_sz_b; // 2 bits
1257 assign ldi_atomic_b = `SPC1.lsu.dcc.atomic_b;
1258 assign ldi_qld_b = `SPC1.lsu.dcc.quad_ldd_b;
1259 assign ldi_ldbl_b = `SPC1.lsu.dcc_ldbl_b;
1260 assign ldi_ldd_b = ldi_ldbl_b & !ldi_qld_b;
1261 assign ldi_bld_b = `SPC1.lsu.dcc.dcc_blk_inst_b;
1262 assign ldi_pf_b = `SPC1.lsu.dcc.pref_inst_b;
1263
1264 // pa, tid are same for LoadIssue and StoreIssue
1265 assign ldi_pa_b = {`SPC1.lsu.tlb_pgnum[39:13],
1266 `SPC1.lsu.lmd.lsu_va_b[12:0]};
1267
1268//---------------------
1269// Load Fill
1270
1271 assign load_fill_e = `SPC1.lsu.dcc.ld_fill_e;
1272 assign ldf_tid_e = `SPC1.lsu.cid.cid_tid;
1273 assign ldf_pa_e = {`SPC1.lsu.lmd.lmd_fill_addr_e[39:3],3'b0};
1274
1275//---------------------
1276// Store Issue
1277
1278 // blk_inst_w will suppress store_w for 1st of 9 cycles on block store.
1279
1280 // If Store to IO ASIs, store issue should not be sent.
1281 // In this case, asi_internal_w is asserted and will suppress store_w.
1282
1283 assign unflushed_store_w = `SPC1.lsu.sbc.unflushed_store_w;
1284
1285 assign store_w = unflushed_store_w &
1286 (~(`PROBES1.asi_internal_w | blk_inst_w) |
1287 bst_in_prog_w);
1288
1289 assign atomic_b = `SPC1.lsu.dcc.atomic_b;
1290 assign rmo_st_b = `SPC1.lsu.sbc_rmo_st_b;
1291 assign blk_inst_b = `SPC1.lsu.dcc.dcc_blk_inst_b;
1292
1293 assign sti_tnum_w = {mycid,sti_tid_w};
1294 assign sti_size_m = `SPC1.lsu.dcc_ldst_bmask;
1295
1296 // flip_size will assert if endian swap for partial store is needed
1297 assign flip_size_b = `SPC1.lsu.dcc.pst_asi_b & `SPC1.lsu.dcc.tlb_tte_ie_b & `SPC1.lsu.dcc.tlb_tte_vld_b & `SPC1.lsu.dcc.st_inst_vld_b;
1298
1299 // Change itype only when control signals are valid
1300 assign sti_itype_w = unflushed_store_w ? itype_w : sti_itype_w;
1301
1302 // It is correct to mix W & B stage signals for this.
1303 // STD is a 2 cycle instruction.
1304 // inst valid in W, data in B (1 cycle behind)
1305 assign sti_data_w = `SPC1.lsu.sbc.std_inst_w ?
1306 sbd_st_data_b :
1307 sbd_st_data_w;
1308 assign sbd_st_data_b = `SPC1.lsu.sbd_st_data_b;
1309
1310 // Use different pa,tid if block store
1311 assign sti_pa_b = bst_in_prog_b ? bst_pa_b : st_pa_b;
1312 assign sti_tid_b = bst_in_prog_b ? bst_tid_b : st_tid_b;
1313
1314 // stxa to IO ASI are already suppressed since store_w will not assert.
1315 // sti_suppress is required to also suppress normal st to IO ASI address range.
1316 assign sti_suppress = (sti_pa_w[39:32] == `IO_ASI_ADDR);
1317
1318 // Normal Store
1319 assign st_pa_b = {`SPC1.lsu.tlb_pgnum[39:13],
1320 `SPC1.lsu.lmd.lsu_va_b[12:0]};
1321 assign st_tid_b = `SPC1.lsu.dcc.tid_b;
1322
1323 // Block Store
1324 assign bst_in_prog_b = `SPC1.lsu.sbc.bst_in_prog_b;
1325 assign bst_pa_b = {`SPC1.lsu.sbd.st_addr_b[39:3],3'b0};
1326 assign bst_tid_b = `SPC1.lsu.sbc.bst_tid;
1327
1328//---------------------
1329// Store Ack
1330
1331assign asi_st_dequeue[7:0] = `SPC1.lsu.dcc_asi_rtn_vld[7:0] &
1332 {8{~`SPC1.lsu.dcc_asi_rtn_rd}};
1333
1334 assign st_ack_no_asi_e = `SPC1.lsu.cic.cic_st_dequeue[7:0] &
1335 ~asi_st_dequeue[7:0] &
1336 ~`SPC1.lsu.cic.sbc_bst_sel[7:0];
1337
1338 assign st_ack_rmo_b = {`SPC1.lsu.sbs7.rmo_st_commit_p4,
1339 `SPC1.lsu.sbs6.rmo_st_commit_p4,
1340 `SPC1.lsu.sbs5.rmo_st_commit_p4,
1341 `SPC1.lsu.sbs4.rmo_st_commit_p4,
1342 `SPC1.lsu.sbs3.rmo_st_commit_p4,
1343 `SPC1.lsu.sbs2.rmo_st_commit_p4,
1344 `SPC1.lsu.sbs1.rmo_st_commit_p4,
1345 `SPC1.lsu.sbs0.rmo_st_commit_p4
1346 };
1347
1348 // It is possible to see 2 threads store_ack in same cycle
1349 // (1 st_ack_no_asi & 1 st_ack_rmo)
1350
1351 assign store_ack_b = st_ack_no_asi_b | st_ack_rmo_b;
1352
1353 // cic_st_atm_cmplt is atomic store completing (same time as store ack)
1354 // (lsu.lmc.dcl2u_err | dcl2nd_err) indicate a data_access_error condition
1355 assign st_data_access_e = {8{(`SPC1.lsu.cic.cic_st_atm_cmplt &
1356 (`SPC1.lsu.lmc.dcl2u_err | `SPC1.lsu.lmc.dcl2nd_err))}} &
1357 `SPC1.lsu.cic.cic_st_dequeue[7:0];
1358//---------------------
1359// Store Inv
1360
1361 // Same as evict_inv_e but with cpq_evict deasserted
1362 assign store_inv_e = `SPC1.lsu.cic_invalidate_e &
1363 (`SPC1.lsu.cic_inv_wen_e!=0)&
1364 ~`SPC1.lsu.cic.cpq_evict &
1365 ~`SPC1.lsu.cic.cid_set_inval &
1366 ~`SPC1.lsu.cic.cic_xinval_e &
1367 ~(`SPC1.lsu.cic.cid_pkt_type[4:0] == 5'b10110);
1368 assign stinv_tnum_e =
1369 {`SPC1.lsu.cid.cpq_data_out[`CPX_VACK_CID],
1370 `SPC1.lsu.cid.cid_tid};
1371
1372//---------------------
1373// Store Update
1374
1375 assign store_update_e = `SPC1.lsu.cic_st_update_e;
1376 assign stu_tid_e = `SPC1.lsu.cid.cid_tid;
1377 assign stu_tnum_e = {mycid,stu_tid_e};
1378
1379 assign l1_index = {`SPC1.lsu.cid.cpq_data_out[116],
1380 `SPC1.lsu.cid.cpq_data_out[115],
1381 `SPC1.lsu.cid.cpq_data_out[114],
1382 `SPC1.lsu.cid.cpq_data_out[113],
1383 `SPC1.lsu.cid.cpq_data_out[112],
1384 `SPC1.lsu.cid.cpq_data_out[122],
1385 `SPC1.lsu.cid.cpq_data_out[121]
1386 };
1387 assign l1_way_select = `SPC1.lsu.cid_inv_vec[17:16];
1388
1389//---------------------
1390// EvictInv
1391
1392 // Same as store_inv_e but with cpq_evict asserted
1393 // LSU can invalidate 1-4 Dcache lines
1394 assign evict_inv_e[3:0] = {4{`SPC1.lsu.cic_invalidate_e & // enable for 4 bit wen below
1395 (`SPC1.lsu.cic_inv_wen_e!=0)&
1396 `SPC1.lsu.cic.cpq_evict &
1397 ~`SPC1.lsu.cic.cid_set_inval &
1398 ~`SPC1.lsu.cic.cic_xinval_e}} &
1399
1400 {|(`SPC1.lsu.cic.evict_inv_wen[15:12]), // 4 bit field - 1 hot. Send evinv when any one set.
1401 |(`SPC1.lsu.cic.evict_inv_wen[11:8]),
1402 |(`SPC1.lsu.cic.evict_inv_wen[7:4]),
1403 |(`SPC1.lsu.cic.evict_inv_wen[3:0])
1404 };
1405
1406 assign evict_srcid_e = `SPC1.lsu.cid.cpq_data_out[114:112];
1407
1408
1409//---------------------
1410// Detect Store to IO ASI in PCX crossbar packet.
1411// This causes next Store Ack to be suppressed.
1412
1413// Normal Store only since atomics are always to cacheable space
1414
1415// Trigger on Store to crossbar.
1416// If Store request is retried on crossbar (due to no grant),
1417// then, st_io_asi will fire multiple times for the same request.
1418// This is OK because it just causes sta_suppress to be set multiple times.
1419
1420 assign pcx_req = `SPC1.spc_pcx_req_pq;
1421 assign pcx_data = `SPC1.spc_pcx_data_pa;
1422
1423 assign st_io_asi = (pcx_req_1 != 9'b0) &
1424 (pcx_data [`PCX_VALID]==1'b1) &
1425 (pcx_data [`PCX_RQTYP]==`CCX_REQ_ST) &
1426 (pcx_data [103:96]==`IO_ASI_ADDR); // Upper byte of 40 bit addr
1427
1428 assign st_io_tid = pcx_data [`PCX_TID];
1429
1430 assign stb_state0_m = `SPC1.lsu.sbs0.stb_state_vld[7:0];
1431 assign stb_state1_m = `SPC1.lsu.sbs1.stb_state_vld[7:0];
1432 assign stb_state2_m = `SPC1.lsu.sbs2.stb_state_vld[7:0];
1433 assign stb_state3_m = `SPC1.lsu.sbs3.stb_state_vld[7:0];
1434 assign stb_state4_m = `SPC1.lsu.sbs4.stb_state_vld[7:0];
1435 assign stb_state5_m = `SPC1.lsu.sbs5.stb_state_vld[7:0];
1436 assign stb_state6_m = `SPC1.lsu.sbs6.stb_state_vld[7:0];
1437 assign stb_state7_m = `SPC1.lsu.sbs7.stb_state_vld[7:0];
1438
1439//---------------------
1440// Load Data (hit only) (See ldst_l2.v for Load Data - miss)
1441
1442 assign load_data_hit = load_w && (hit_w | fraw_w);
1443 assign ld_miss_b = `SPC1.lsu.dcc.dcc_ld_miss_b;
1444 assign fraw_w = `SPC1.lsu.lmc.ld_raw_bypass_w;
1445 assign hit_w = ~ld_miss_w & ~stb_hit_w;
1446 assign miss_w = ~fraw_w & (ld_miss_w | stb_hit_w);
1447
1448//---------------------
1449// Load Pop
1450
1451 assign perfmon_g = `SPC1.lsu.lsu_perfmon_trap_g;
1452 assign perfmon_tid_g = `SPC1.lsu.lsu_dcerr_tid_g;
1453 // perfmon_mask will not fire if trap is not enabled or higher priority trap is taken.
1454 assign perfmon_mask_g = {`SPC1.tlu.fls1.pil_mask_15[3:0], `SPC1.tlu.fls0.pil_mask_15[3:0]} &
1455 ~{8 {`SPC1.lsu_dcl2u_err_g | `SPC1.lsu_dcl2nd_err_g}};
1456
1457 assign perfmon = perfmon_w;
1458 assign perfmon_tid = perfmon_tid_w;
1459 assign perfmon_tnum = {mycid,perfmon_tid_w};
1460 assign perfmon_mask = perfmon_mask_w;
1461
1462
1463
1464//---------------------
1465// Store Pop
1466
1467 assign bst_kill = {`SPC1.lsu.sbs7.bst_kill,
1468 `SPC1.lsu.sbs6.bst_kill,
1469 `SPC1.lsu.sbs5.bst_kill,
1470 `SPC1.lsu.sbs4.bst_kill,
1471 `SPC1.lsu.sbs3.bst_kill,
1472 `SPC1.lsu.sbs2.bst_kill,
1473 `SPC1.lsu.sbs1.bst_kill,
1474 `SPC1.lsu.sbs0.bst_kill};
1475
1476//----------------------------------------------------------
1477//----------------------------------------------------------
1478
1479always @ (posedge `SPC1.l2clk) begin // {
1480
1481 tstamp = `TOP.core_cycle_cnt - 1;
1482
1483 //------------------------------
1484 // Pipeline from B to W
1485
1486 ldi_pa_w <= ldi_pa_b;
1487 ld_miss_w <= ld_miss_b;
1488 stb_hit_w <= `SPC1.lsu.stb_cam_hit;
1489 ldi_pf_w <= ldi_pf_b;
1490 ldi_size_w <= ldi_size_b;
1491 load_fill_m <= load_fill_e;
1492 load_fill_b <= load_fill_m;
1493 load_fill_w <= load_fill_b;
1494 ldf_tid_m <= ldf_tid_e;
1495 ldf_tid_b <= ldf_tid_m;
1496 ldf_tid_w <= ldf_tid_b;
1497 ldf_pa_m <= ldf_pa_e;
1498 ldf_pa_b <= ldf_pa_m;
1499 ldf_pa_w <= ldf_pa_b;
1500
1501 sti_size_b <= sti_size_m;
1502 sti_size_w <= (flip_size_b) ? {sti_size_b[0],sti_size_b[1],sti_size_b[2],sti_size_b[3],
1503 sti_size_b[4],sti_size_b[5],sti_size_b[6],sti_size_b[7]}
1504 : sti_size_b;
1505 sti_pa_w <= sti_pa_b;
1506 sti_tid_w <= sti_tid_b;
1507 st_ack_no_asi_m <= st_ack_no_asi_e;
1508 st_ack_no_asi_b <= st_ack_no_asi_m;
1509 st_data_access_m <= st_data_access_e;
1510 st_data_access_b <= st_data_access_m;
1511 st_data_access_w <= st_data_access_b;
1512 store_ack_w <= store_ack_b;
1513 store_update_m <= store_update_e;
1514 store_update_b <= store_update_m;
1515 store_update_w <= store_update_b;
1516 store_inv_m <= store_inv_e;
1517 store_inv_b <= store_inv_m;
1518 store_inv_w <= store_inv_b;
1519 stinv_tnum_m <= stinv_tnum_e;
1520 stinv_tnum_b <= stinv_tnum_m;
1521 stinv_tnum_w <= stinv_tnum_b;
1522 st_ack_rmo_w <= st_ack_rmo_b;
1523 stu_tid_m <= stu_tid_e;
1524 stu_tid_b <= stu_tid_m;
1525 stu_tid_w <= stu_tid_b;
1526 stu_tnum_m <= stu_tnum_e;
1527 stu_tnum_b <= stu_tnum_m;
1528 stu_tnum_w <= stu_tnum_b;
1529 store_pa_b <= store_pa_m;
1530 store_pa_w <= store_pa_b;
1531 bst_in_prog_w <= bst_in_prog_b;
1532 blk_inst_w <= blk_inst_b;
1533 sbd_st_data_w <= sbd_st_data_b;
1534 evict_inv_m <= evict_inv_e;
1535 evict_inv_b <= evict_inv_m;
1536 evict_inv_w <= evict_inv_b;
1537 evict_srcid_m <= evict_srcid_e;
1538 evict_srcid_b <= evict_srcid_m;
1539 evict_srcid_w <= evict_srcid_b;
1540 pcx_req_1 <= pcx_req;
1541 stb_state0_b <= stb_state0_m;
1542 stb_state1_b <= stb_state1_m;
1543 stb_state2_b <= stb_state2_m;
1544 stb_state3_b <= stb_state3_m;
1545 stb_state4_b <= stb_state4_m;
1546 stb_state5_b <= stb_state5_m;
1547 stb_state6_b <= stb_state6_m;
1548 stb_state7_b <= stb_state7_m;
1549 stb_state0_w <= stb_state0_b;
1550 stb_state1_w <= stb_state1_b;
1551 stb_state2_w <= stb_state2_b;
1552 stb_state3_w <= stb_state3_b;
1553 stb_state4_w <= stb_state4_b;
1554 stb_state5_w <= stb_state5_b;
1555 stb_state6_w <= stb_state6_b;
1556 stb_state7_w <= stb_state7_b;
1557
1558 perfmon_m <= perfmon_g;
1559 perfmon_b <= perfmon_m;
1560 perfmon_w <= perfmon_b;
1561 perfmon_tid_m <= perfmon_tid_g;
1562 perfmon_tid_b <= perfmon_tid_m;
1563 perfmon_tid_w <= perfmon_tid_b;
1564 perfmon_mask_m <= perfmon_mask_g;
1565 perfmon_mask_b <= perfmon_mask_m;
1566 perfmon_mask_w <= perfmon_mask_b;
1567
1568 //----------------------------------------------------------
1569 // Calculate pa for STUPDATE and STINV
1570 // Moved this into the always block to avoid the constant
1571 // probing of the dtag memory structure.
1572
1573 if (store_inv_e | store_update_e) begin // {
1574 store_pa_m[2:0] <= 3'b000;
1575 store_pa_m[10:3] <= {`SPC1.lsu.cid.cpq_data_out[116],
1576 `SPC1.lsu.cid.cpq_data_out[115],
1577 `SPC1.lsu.cid.cpq_data_out[114],
1578 `SPC1.lsu.cid.cpq_data_out[113],
1579 `SPC1.lsu.cid.cpq_data_out[112],
1580 `SPC1.lsu.cid.cpq_data_out[122],
1581 `SPC1.lsu.cid.cpq_data_out[121],
1582 `SPC1.lsu.cid.cpq_data_out[104]
1583 };
1584 store_pa_m[38:11] <= (l1_way_select==2'h0) ? dta_way0[l1_index] :
1585 (l1_way_select==2'h1) ? dta_way1[l1_index] :
1586 (l1_way_select==2'h2) ? dta_way2[l1_index] : dta_way3[l1_index];
1587 store_pa_m[39] <= 1'b0; // Only memory stores get inv/update
1588 end // }
1589
1590
1591 // After Store to IO ASI is detected at StI time, suppress the next Store Ack
1592 // There is only 1 store to IO ASI active at one time per thread because
1593 // that is all the LSU allows.
1594 if (st_io_asi) begin
1595 sta_suppress [st_io_tid] <= 1'b1;
1596 end
1597
1598 case ({ldi_atomic_b,ldi_bld_b,ldi_ldd_b,ldi_qld_b,ldi_pf_b})
1599 5'b00000: ldi_itype_w <= `ITYPE_LOAD;
1600 5'b00001: ldi_itype_w <= `ITYPE_PREFETCH;
1601 5'b00010: ldi_itype_w <= `ITYPE_QUAD_LOAD;
1602 5'b00100: ldi_itype_w <= `ITYPE_DOUBLE_LOAD;
1603 5'b01000: ldi_itype_w <= `ITYPE_BLOCK_LOAD;
1604 5'b10000: ldi_itype_w <= `ITYPE_ATOMIC;
1605 default: ldi_itype_w <= `ITYPE_NO; // Illegal
1606 endcase
1607
1608 case ({atomic_b,rmo_st_b,bst_in_prog_b})
1609 3'b000: itype_w <= `ITYPE_STORE;
1610 3'b010: itype_w <= `ITYPE_BLK_INIT_ST;
1611 3'b011: itype_w <= `ITYPE_BLOCK_STORE;
1612 3'b100: itype_w <= `ITYPE_ATOMIC;
1613 3'b001,
1614 3'b101,
1615 3'b110,
1616 3'b111: itype_w <= `ITYPE_NO; // Illegal
1617 endcase
1618
1619 //----------------------------------------------------------
1620 //----------------------------------------------------------
1621 // Load Issue
1622
1623 // Load Issue must be before Store Issue for atomic
1624
1625 if (load_w) begin // {
1626
1627 if (ldi_suppress==1'b0) begin // {
1628 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
1629 `PR_INFO ("pli_ldst", `INFO,
1630 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h size=%h typ=%0h ts=%0d",
1631 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
1632 junk = $sim_send(`PLI_MEM_LD_ISSUE,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
1633 end // }
1634 end // }
1635 else begin // {
1636 `PR_INFO ("pli_ldst", `INFO,
1637 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h Suppress for IO ASI",mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w);
1638 end // }
1639
1640 if (`PARGS.show_memop_on) begin // {
1641 `PR_NORMAL ("pli_ldst", `NORMAL,
1642 "C%0d T%0d MEMOP_LOAD tid=%d pa=%h ts=%0d (LSU - W stage)",
1643 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,tstamp);
1644 end // }
1645
1646 end // }
1647
1648 //----------------------------------------------------------
1649 //----------------------------------------------------------
1650 // Load Data (hit only) (See ldst_l2.v for Load Data - miss)
1651
1652 if (load_data_hit) begin // {
1653
1654 dsrc = hit_w ? `DSRC_L1 : `DSRC_STB;
1655
1656 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
1657 `PR_INFO ("pli_ldst", `INFO,
1658 "C%0d T%0d PLI_MEM_LDDATA tid=%d pa=%h dsrc=%0h ts=%0d",
1659 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
1660 junk = $sim_send(`PLI_MEM_LD_DATA,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
1661 end // }
1662
1663 end // }
1664
1665
1666 //----------------------------------------------------------
1667 //----------------------------------------------------------
1668 // Store Ack
1669 //
1670 // Store Ack cmd must be sent before Store Inv, Store Update for NAS
1671 // Store Ack & Store Update will be in the same timestamp
1672
1673 if (store_ack_w != 8'b0) begin // {
1674
1675 for (i=0; i<=7; i=i+1) begin // {
1676 if (store_ack_w[i]) begin // {
1677 sta_tid = i[2:0];
1678 sta_tnum = {mycid,sta_tid};
1679 sta_rmo = st_ack_rmo_w[i];
1680
1681 if (sta_suppress[sta_tid]==1'b0) begin // {
1682 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
1683 `PR_INFO ("pli_ldst", `INFO,
1684 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
1685 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
1686 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
1687 end // }
1688 end // }
1689
1690 else begin // {
1691
1692 // It is possible for 2 Stores it be in flight because of the delay from CPQ push & pop.
1693 // So, make sure Bench is suppressing the correct Store.
1694 case (sta_tid)
1695 3'h0: stb_state=stb_state0_w;
1696 3'h1: stb_state=stb_state1_w;
1697 3'h2: stb_state=stb_state2_w;
1698 3'h3: stb_state=stb_state3_w;
1699 3'h4: stb_state=stb_state4_w;
1700 3'h5: stb_state=stb_state5_w;
1701 3'h6: stb_state=stb_state6_w;
1702 3'h7: stb_state=stb_state7_w;
1703 default:
1704 `PR_ERROR ("pli_ldst", `ERROR,
1705 "C%0d T%0d PLI_MEM_XXX Bench Error. Should never execute case default",mycid,sta_tid);
1706 endcase
1707
1708 // If stb_state has only 1 bit asserted, then suppress the STACK. Otherwise, send the STACK.
1709 case (stb_state) // {
1710 8'b0000_0000: begin
1711 `PR_ERROR ("pli_ldst", `ERROR,
1712 "C%0d T%0d PLI_MEM_XXX Bench Error. stb_state should not be 8'b0",
1713 mycid,sta_tid);
1714 end
1715 8'b0000_0001,
1716 8'b0000_0010,
1717 8'b0000_0100,
1718 8'b0000_1000,
1719 8'b0001_0000,
1720 8'b0010_0000,
1721 8'b0100_0000,
1722 8'b1000_0000: stb_last = 1'b1;
1723 default: stb_last = 1'b0;
1724 endcase // }
1725
1726 if (stb_last==1'b0) begin // {
1727 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
1728 `PR_INFO ("pli_ldst", `INFO,
1729 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
1730 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
1731 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
1732 end // }
1733 end // }
1734 else begin // {
1735 sta_suppress[sta_tid] <= 1'b0;
1736 `PR_INFO ("pli_ldst", `INFO,
1737 "C%0d T%0d PLI_MEM_STACK tid=%d Suppress for IO ASI",mycid,sta_tid,sta_tnum);
1738 end // }
1739 end // }
1740
1741 end // if (store_ack_w[i]) }
1742 end // for }
1743
1744 end // if (store_ack_w) }
1745
1746 //----------------------------------------------------------
1747 //----------------------------------------------------------
1748 // Store Inv
1749
1750 if (store_inv_w) begin // {
1751
1752 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stinv_tnum_w]) begin // {
1753 `PR_INFO ("pli_ldst", `INFO,
1754 "C%0d PLI_MEM_STINV tid=%d pa=%h cid=%h ts=%0d",
1755 mycid,stinv_tnum_w,store_pa_w,mycid,tstamp);
1756 junk = $sim_send(`PLI_MEM_ST_INV,mycid,stinv_tnum_w,store_pa_w,tstamp);
1757 end // }
1758
1759 end // }
1760
1761
1762 //----------------------------------------------------------
1763 //----------------------------------------------------------
1764 // Store Update
1765
1766 if (store_update_w) begin // {
1767
1768 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stu_tnum_w]) begin // {
1769 `PR_INFO ("pli_ldst", `INFO,
1770 "C%0d T%0d PLI_MEM_STUP tid=%d pa=%h ts=%0d",
1771 mycid,stu_tid_w,stu_tnum_w,store_pa_w,tstamp);
1772 junk = $sim_send(`PLI_MEM_ST_UPDATE,stu_tnum_w,store_pa_w,tstamp);
1773 end // }
1774
1775 end // }
1776
1777 //----------------------------------------------------------
1778 //----------------------------------------------------------
1779 // Load Fill
1780
1781 if (load_fill_w) begin // {
1782
1783 ldf_tnum_w = {mycid,ldf_tid_w};
1784
1785 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldf_tnum_w]) begin // {
1786 `PR_INFO ("pli_ldst", `INFO,
1787 "C%0d T%0d PLI_MEM_LDFILL tid=%d pa=%h ts=%0d",
1788 mycid,ldf_tid_w,ldf_tnum_w,ldf_pa_w,tstamp);
1789 junk = $sim_send(`PLI_MEM_LD_FILL,ldf_tnum_w,ldf_pa_w,tstamp);
1790 end // }
1791
1792 end // }
1793
1794 //----------------------------------------------------------
1795 //----------------------------------------------------------
1796 // Store Issue
1797
1798 if (store_w) begin // {
1799
1800 if (sti_suppress==1'b0) begin // {
1801 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sti_tnum_w]) begin // {
1802 `PR_INFO ("pli_ldst", `INFO,
1803 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h data=%h sz=%h typ=%0h ts=%0d",
1804 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
1805 junk = $sim_send(`PLI_MEM_ST_ISSUE,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
1806 end // }
1807
1808 end // }
1809 else begin // {
1810 `PR_INFO ("pli_ldst", `INFO,
1811 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h Suppress for IO ASI",mycid,sti_tid_w,sti_tnum_w,sti_pa_w);
1812 end // }
1813
1814 if (`PARGS.show_memop_on) begin // {
1815 `PR_NORMAL ("pli_ldst", `NORMAL,
1816 "C%0d T%0d MEMOP_STORE tid=%d pa=%h data=%h sz=%h ts=%0d (LSU - W stage)",
1817 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,tstamp);
1818 end // }
1819
1820 end // }
1821
1822 //----------------------------------------------------------
1823 //----------------------------------------------------------
1824 // EvictInv
1825 // Send 1-4 EvictInv messages per cycle - based on how many Dcache lines were invalidated.
1826
1827 for (i=0; i<=3; i=i+1) begin // {
1828 if (evict_inv_w[i]) begin // {
1829
1830 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on) begin // {
1831 `PR_INFO ("pli_ldst", `INFO,
1832 "C%0d PLI_MEM_EVINV cid=%d srcid=%0d ts=%0d",
1833 mycid,mycid,evict_srcid_w,tstamp);
1834 junk = $sim_send(`PLI_MEM_EVICT_INV,mycid,evict_srcid_w,tstamp);
1835 end // }
1836
1837 end // }
1838 end // }
1839
1840 //----------------------------------------------------------
1841 //----------------------------------------------------------
1842 // Load Pop - special case
1843
1844 // This is required in case of a performance monitor trap due to L2 miss.
1845 // In this case, the trap is not indicated until after the Load pkt returns to the LSU.
1846 // ldst_sync has already sent LDISSUE and LDDATA to Riesling. But, the Load is not executed.
1847 // Load Pop tells Riesling to pop the LDISSUE,LDDATA off of its queues.
1848
1849 if (perfmon & perfmon_mask[perfmon_tid]) begin // {
1850
1851 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[perfmon_tnum]) begin // {
1852 `PR_INFO ("pli_ldst", `INFO,
1853 "C%0d T%0d PLI_MEM_LDPOP tid=%d ts=%0d",
1854 mycid,perfmon_tid,perfmon_tnum,tstamp);
1855 junk = $sim_send(`PLI_MEM_LD_POP,perfmon_tnum);
1856 end // }
1857
1858 end // }
1859
1860 //----------------------------------------------------------
1861 //----------------------------------------------------------
1862 // Store Pop - special cases
1863
1864 // This is required in case of a FRF error trap (internal_proc_error) on a Block Store.
1865 // In this case, the trap is not indicated until after the 8 STISSUE has been sent to Riesling.
1866 // But, the Store is not executed.
1867 // Store Pop tells Riesling to pop the 8 STISSUE off of its queues.
1868
1869 if (bst_kill!==8'b0) begin // {
1870
1871 for (i=0;i<=7;i=i+1) begin
1872 if (bst_kill[i]==1'b1) begin
1873 bst_kill_tid = i;
1874 bst_kill_tnum = {mycid,bst_kill_tid};
1875
1876 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[bst_kill_tnum]) begin // {
1877 `PR_INFO ("pli_ldst", `INFO,
1878 "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
1879 mycid,bst_kill_tid,bst_kill_tnum,tstamp);
1880 junk = $sim_send(`PLI_MEM_ST_POP,bst_kill_tnum);
1881 end // }
1882 end
1883 end
1884
1885 end // }
1886
1887 //--------------------
1888 // This is required for data_access_error on atomic. In this case, Riesling only cleans up the Load,
1889 // but doesn't know it is an atomic so Riesling doesn't clean up the store in its buffers.
1890 // The STPOP tells Riesling to clear the newest Store from the buffers.
1891 // It is possible to have older Stores in-flight but not newer Stores in-flight.
1892
1893// if (st_data_access_w != 8'b0) begin // {
1894//
1895// for (i=0; i<=7; i=i+1) begin // {
1896// if (st_data_access_w[i]) begin // {
1897// tmp_tid = i[2:0];
1898// tmp_tnum = {mycid,tmp_tid};
1899//
1900// if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[tmp_tnum]) begin // {
1901// `PR_INFO ("pli_ldst", `INFO,
1902// "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
1903// mycid,tmp_tid,tmp_tnum,tstamp);
1904// junk = $sim_send(`PLI_MEM_ST_POP,tmp_tnum);
1905// end // }
1906// end // } if st_data_access[i]
1907// end // } for
1908// end // } if st_data_access
1909
1910end // always }
1911
1912//----------------------------------------------------------
1913// Need to model the D arrays to get PA's for store updates and invalidates
1914
1915always @ (negedge `SPC1.l2clk) begin // {
1916 if (`SPC1.lsu.dta.wr_way[0])
1917 dta_way0[`SPC1.lsu.dta.index_y[6:0]] <= `SPC1.lsu.dta.wrtag_y[27:0];
1918 if (`SPC1.lsu.dta.wr_way[1])
1919 dta_way1[`SPC1.lsu.dta.index_y[6:0]] <= `SPC1.lsu.dta.wrtag_y[27:0];
1920 if (`SPC1.lsu.dta.wr_way[2])
1921 dta_way2[`SPC1.lsu.dta.index_y[6:0]] <= `SPC1.lsu.dta.wrtag_y[27:0];
1922 if (`SPC1.lsu.dta.wr_way[3])
1923 dta_way3[`SPC1.lsu.dta.index_y[6:0]] <= `SPC1.lsu.dta.wrtag_y[27:0];
1924end // always }
1925
1926//----------------------------------------------------------
1927`endif
1928endmodule
1929
1930`endif
1931`ifdef CORE_2
1932
1933module ldst_lsu_c2 ();
1934`ifndef GATESIM
1935
1936// common defines
1937`include "defines.vh"
1938`include "nas.vh"
1939// PCX/CPX packet defines (see :/verif/env/common/vera/include)
1940`include "ccx.vri"
1941`include "cmp.vri"
1942
1943//---------------------
1944// Load Signals
1945wire load_w;
1946
1947wire ldi_suppress;
1948wire [2:0] ldi_tid_w;
1949wire [5:0] ldi_tnum_w;
1950wire [39:0] ldi_pa_b;
1951reg [39:0] ldi_pa_w;
1952wire [1:0] ldi_size_b;
1953reg [1:0] ldi_size_w;
1954wire ldi_bld_b;
1955wire ldi_qld_b;
1956wire ldi_ldbl_b;
1957wire ldi_ldd_b;
1958wire ldi_atomic_b;
1959wire ldi_pf_b;
1960reg ldi_pf_w;
1961reg [7:0] ldi_itype_w;
1962reg [7:0] dsrc;
1963
1964wire ld_miss_b;
1965reg ld_miss_w;
1966reg stb_hit_w;
1967wire fraw_w;
1968wire hit_w;
1969wire miss_w;
1970wire load_data_hit;
1971
1972wire load_fill_e;
1973reg load_fill_m;
1974reg load_fill_b;
1975reg load_fill_w;
1976wire [2:0] ldf_tid_e;
1977reg [2:0] ldf_tid_m;
1978reg [2:0] ldf_tid_b;
1979reg [2:0] ldf_tid_w;
1980reg [5:0] ldf_tnum_w;
1981wire [39:0] ldf_pa_e;
1982reg [39:0] ldf_pa_m;
1983reg [39:0] ldf_pa_b;
1984reg [39:0] ldf_pa_w;
1985
1986//---------------------
1987// Store Signals
1988wire unflushed_store_w;
1989wire store_w;
1990wire sti_suppress;
1991wire [2:0] sti_tid_b;
1992reg [2:0] sti_tid_w;
1993wire [5:0] sti_tnum_w;
1994wire [39:0] sti_pa_b;
1995reg [39:0] sti_pa_w;
1996wire [63:0] sti_data_w;
1997wire [7:0] sti_size_m;
1998reg [7:0] sti_size_b;
1999reg [7:0] sti_size_w;
2000wire [7:0] sti_itype_w;
2001reg [7:0] itype_w;
2002wire [63:0] sbd_st_data_b;
2003reg [63:0] sbd_st_data_w;
2004wire flip_size_b;
2005
2006wire atomic_b;
2007wire rmo_st_b;
2008wire blk_inst_b;
2009reg blk_inst_w;
2010
2011wire bst_in_prog_b;
2012reg bst_in_prog_w;
2013wire [39:0] bst_pa_b;
2014reg [39:0] bst_pa_w;
2015wire [2:0] bst_tid_b;
2016reg [2:0] bst_tid_w;
2017wire [39:0] st_pa_b;
2018reg [39:0] st_pa_w;
2019wire [2:0] st_tid_b;
2020reg [2:0] st_tid_w;
2021
2022wire store_inv_e;
2023reg store_inv_m;
2024reg store_inv_b;
2025reg store_inv_w;
2026wire [5:0] stinv_tnum_e;
2027reg [5:0] stinv_tnum_m;
2028reg [5:0] stinv_tnum_b;
2029reg [5:0] stinv_tnum_w;
2030
2031wire store_update_e;
2032reg store_update_m;
2033reg store_update_b;
2034reg store_update_w;
2035wire [2:0] stu_tid_e;
2036reg [2:0] stu_tid_m;
2037reg [2:0] stu_tid_b;
2038reg [2:0] stu_tid_w;
2039wire [5:0] stu_tnum_e;
2040reg [5:0] stu_tnum_m;
2041reg [5:0] stu_tnum_b;
2042reg [5:0] stu_tnum_w;
2043
2044wire [7:0] asi_st_dequeue;
2045wire [7:0] st_ack_no_asi_e;
2046reg [7:0] st_ack_no_asi_m;
2047reg [7:0] st_ack_no_asi_b;
2048wire [7:0] store_ack_b;
2049reg [7:0] store_ack_w;
2050wire [7:0] st_ack_rmo_b;
2051reg [7:0] st_ack_rmo_w;
2052reg sta_rmo;
2053reg [2:0] sta_tid;
2054reg [5:0] sta_tnum;
2055reg sta_suppress [0:7]; // 1 per thread
2056wire st_io_asi;
2057wire [2:0] st_io_tid;
2058wire [7:0] st_data_access_e;
2059reg [7:0] st_data_access_m;
2060reg [7:0] st_data_access_b;
2061reg [7:0] st_data_access_w;
2062reg [2:0] tmp_tid;
2063reg [5:0] tmp_tnum;
2064
2065reg [39:0] store_pa_m;
2066reg [39:0] store_pa_b;
2067reg [39:0] store_pa_w;
2068
2069wire [1:0] l1_way_select;
2070wire [6:0] l1_index;
2071wire [27:0] my_way;
2072wire [27:0] way0;
2073wire [27:0] way1;
2074wire [27:0] way2;
2075wire [27:0] way3;
2076
2077wire [3:0] evict_inv_e;
2078reg [3:0] evict_inv_m;
2079reg [3:0] evict_inv_b;
2080reg [3:0] evict_inv_w;
2081wire [2:0] evict_srcid_e;
2082reg [2:0] evict_srcid_m;
2083reg [2:0] evict_srcid_b;
2084reg [2:0] evict_srcid_w;
2085
2086wire [8:0] pcx_req;
2087reg [8:0] pcx_req_1;
2088wire [129:0] pcx_data;
2089
2090wire perfmon;
2091wire perfmon_g;
2092reg perfmon_m;
2093reg perfmon_b;
2094reg perfmon_w;
2095wire [2:0] perfmon_tid;
2096wire [2:0] perfmon_tid_g;
2097reg [2:0] perfmon_tid_m;
2098reg [2:0] perfmon_tid_b;
2099reg [2:0] perfmon_tid_w;
2100wire [5:0] perfmon_tnum;
2101wire [7:0] perfmon_mask;
2102wire [7:0] perfmon_mask_g;
2103reg [7:0] perfmon_mask_m;
2104reg [7:0] perfmon_mask_b;
2105reg [7:0] perfmon_mask_w;
2106
2107wire [7:0] bst_kill;
2108reg [2:0] bst_kill_tid;
2109reg [5:0] bst_kill_tnum;
2110
2111wire [7:0] stb_state0_m;
2112wire [7:0] stb_state1_m;
2113wire [7:0] stb_state2_m;
2114wire [7:0] stb_state3_m;
2115wire [7:0] stb_state4_m;
2116wire [7:0] stb_state5_m;
2117wire [7:0] stb_state6_m;
2118wire [7:0] stb_state7_m;
2119reg [7:0] stb_state0_b;
2120reg [7:0] stb_state1_b;
2121reg [7:0] stb_state2_b;
2122reg [7:0] stb_state3_b;
2123reg [7:0] stb_state4_b;
2124reg [7:0] stb_state5_b;
2125reg [7:0] stb_state6_b;
2126reg [7:0] stb_state7_b;
2127reg [7:0] stb_state0_w;
2128reg [7:0] stb_state1_w;
2129reg [7:0] stb_state2_w;
2130reg [7:0] stb_state3_w;
2131reg [7:0] stb_state4_w;
2132reg [7:0] stb_state5_w;
2133reg [7:0] stb_state6_w;
2134reg [7:0] stb_state7_w;
2135reg [7:0] stb_state;
2136reg stb_last;
2137
2138// Copy of dtag
2139reg [27:0] dta_way0 [127:0];
2140reg [27:0] dta_way1 [127:0];
2141reg [27:0] dta_way2 [127:0];
2142reg [27:0] dta_way3 [127:0];
2143
2144//---------------------
2145// Misc Signals
2146wire [2:0] mycid;
2147integer tstamp;
2148integer junk;
2149integer i;
2150
2151initial begin // {
2152 ldf_tnum_w = 6'b0;
2153 dsrc = 2'b0;
2154 sta_tid = 3'b0;
2155 sta_tnum = 6'b0;
2156 for (i=0; i<=7; i=i+1) begin
2157 sta_suppress[i] = 1'b0;
2158 end
2159
2160end // }
2161
2162// for debug only - allows display in Debussy
2163wire sta_suppress0;
2164wire sta_suppress1;
2165wire sta_suppress2;
2166wire sta_suppress3;
2167wire sta_suppress4;
2168wire sta_suppress5;
2169wire sta_suppress6;
2170wire sta_suppress7;
2171
2172 assign sta_suppress0 = sta_suppress[0];
2173 assign sta_suppress1 = sta_suppress[1];
2174 assign sta_suppress2 = sta_suppress[2];
2175 assign sta_suppress3 = sta_suppress[3];
2176 assign sta_suppress4 = sta_suppress[4];
2177 assign sta_suppress5 = sta_suppress[5];
2178 assign sta_suppress6 = sta_suppress[6];
2179 assign sta_suppress7 = sta_suppress[7];
2180
2181//----------------------------------------------------------
2182//----------------------------------------------------------
2183// DUT probes
2184
2185 assign mycid = 2;
2186
2187//---------------------
2188// Load Issue
2189
2190 // If Load to IO ASIs, load issue should not be sent.
2191 // In this case, asi_internal_w is asserted and will suppress load_w.
2192
2193 assign load_w = `SPC2.lsu.dcc.ld_inst_vld_w &
2194 ~`PROBES2.asi_internal_w &
2195 ~`SPC2.lsu.dcc.flush_w &
2196 ~ldi_pf_w;
2197
2198 // ldxa to IO ASI are already suppressed since load_w will not assert.
2199 // ldi_suppress is required to also suppress normal ld to IO ASI address range.
2200 assign ldi_suppress = (ldi_pa_w[39:32] == `IO_ASI_ADDR);
2201
2202 assign ldi_tid_w = `SPC2.lsu.dcc.tid_w;
2203 assign ldi_tnum_w = {mycid,ldi_tid_w};
2204 assign ldi_size_b = `SPC2.lsu.dcc.ldst_sz_b; // 2 bits
2205 assign ldi_atomic_b = `SPC2.lsu.dcc.atomic_b;
2206 assign ldi_qld_b = `SPC2.lsu.dcc.quad_ldd_b;
2207 assign ldi_ldbl_b = `SPC2.lsu.dcc_ldbl_b;
2208 assign ldi_ldd_b = ldi_ldbl_b & !ldi_qld_b;
2209 assign ldi_bld_b = `SPC2.lsu.dcc.dcc_blk_inst_b;
2210 assign ldi_pf_b = `SPC2.lsu.dcc.pref_inst_b;
2211
2212 // pa, tid are same for LoadIssue and StoreIssue
2213 assign ldi_pa_b = {`SPC2.lsu.tlb_pgnum[39:13],
2214 `SPC2.lsu.lmd.lsu_va_b[12:0]};
2215
2216//---------------------
2217// Load Fill
2218
2219 assign load_fill_e = `SPC2.lsu.dcc.ld_fill_e;
2220 assign ldf_tid_e = `SPC2.lsu.cid.cid_tid;
2221 assign ldf_pa_e = {`SPC2.lsu.lmd.lmd_fill_addr_e[39:3],3'b0};
2222
2223//---------------------
2224// Store Issue
2225
2226 // blk_inst_w will suppress store_w for 1st of 9 cycles on block store.
2227
2228 // If Store to IO ASIs, store issue should not be sent.
2229 // In this case, asi_internal_w is asserted and will suppress store_w.
2230
2231 assign unflushed_store_w = `SPC2.lsu.sbc.unflushed_store_w;
2232
2233 assign store_w = unflushed_store_w &
2234 (~(`PROBES2.asi_internal_w | blk_inst_w) |
2235 bst_in_prog_w);
2236
2237 assign atomic_b = `SPC2.lsu.dcc.atomic_b;
2238 assign rmo_st_b = `SPC2.lsu.sbc_rmo_st_b;
2239 assign blk_inst_b = `SPC2.lsu.dcc.dcc_blk_inst_b;
2240
2241 assign sti_tnum_w = {mycid,sti_tid_w};
2242 assign sti_size_m = `SPC2.lsu.dcc_ldst_bmask;
2243
2244 // flip_size will assert if endian swap for partial store is needed
2245 assign flip_size_b = `SPC2.lsu.dcc.pst_asi_b & `SPC2.lsu.dcc.tlb_tte_ie_b & `SPC2.lsu.dcc.tlb_tte_vld_b & `SPC2.lsu.dcc.st_inst_vld_b;
2246
2247 // Change itype only when control signals are valid
2248 assign sti_itype_w = unflushed_store_w ? itype_w : sti_itype_w;
2249
2250 // It is correct to mix W & B stage signals for this.
2251 // STD is a 2 cycle instruction.
2252 // inst valid in W, data in B (1 cycle behind)
2253 assign sti_data_w = `SPC2.lsu.sbc.std_inst_w ?
2254 sbd_st_data_b :
2255 sbd_st_data_w;
2256 assign sbd_st_data_b = `SPC2.lsu.sbd_st_data_b;
2257
2258 // Use different pa,tid if block store
2259 assign sti_pa_b = bst_in_prog_b ? bst_pa_b : st_pa_b;
2260 assign sti_tid_b = bst_in_prog_b ? bst_tid_b : st_tid_b;
2261
2262 // stxa to IO ASI are already suppressed since store_w will not assert.
2263 // sti_suppress is required to also suppress normal st to IO ASI address range.
2264 assign sti_suppress = (sti_pa_w[39:32] == `IO_ASI_ADDR);
2265
2266 // Normal Store
2267 assign st_pa_b = {`SPC2.lsu.tlb_pgnum[39:13],
2268 `SPC2.lsu.lmd.lsu_va_b[12:0]};
2269 assign st_tid_b = `SPC2.lsu.dcc.tid_b;
2270
2271 // Block Store
2272 assign bst_in_prog_b = `SPC2.lsu.sbc.bst_in_prog_b;
2273 assign bst_pa_b = {`SPC2.lsu.sbd.st_addr_b[39:3],3'b0};
2274 assign bst_tid_b = `SPC2.lsu.sbc.bst_tid;
2275
2276//---------------------
2277// Store Ack
2278
2279assign asi_st_dequeue[7:0] = `SPC2.lsu.dcc_asi_rtn_vld[7:0] &
2280 {8{~`SPC2.lsu.dcc_asi_rtn_rd}};
2281
2282 assign st_ack_no_asi_e = `SPC2.lsu.cic.cic_st_dequeue[7:0] &
2283 ~asi_st_dequeue[7:0] &
2284 ~`SPC2.lsu.cic.sbc_bst_sel[7:0];
2285
2286 assign st_ack_rmo_b = {`SPC2.lsu.sbs7.rmo_st_commit_p4,
2287 `SPC2.lsu.sbs6.rmo_st_commit_p4,
2288 `SPC2.lsu.sbs5.rmo_st_commit_p4,
2289 `SPC2.lsu.sbs4.rmo_st_commit_p4,
2290 `SPC2.lsu.sbs3.rmo_st_commit_p4,
2291 `SPC2.lsu.sbs2.rmo_st_commit_p4,
2292 `SPC2.lsu.sbs1.rmo_st_commit_p4,
2293 `SPC2.lsu.sbs0.rmo_st_commit_p4
2294 };
2295
2296 // It is possible to see 2 threads store_ack in same cycle
2297 // (1 st_ack_no_asi & 1 st_ack_rmo)
2298
2299 assign store_ack_b = st_ack_no_asi_b | st_ack_rmo_b;
2300
2301 // cic_st_atm_cmplt is atomic store completing (same time as store ack)
2302 // (lsu.lmc.dcl2u_err | dcl2nd_err) indicate a data_access_error condition
2303 assign st_data_access_e = {8{(`SPC2.lsu.cic.cic_st_atm_cmplt &
2304 (`SPC2.lsu.lmc.dcl2u_err | `SPC2.lsu.lmc.dcl2nd_err))}} &
2305 `SPC2.lsu.cic.cic_st_dequeue[7:0];
2306//---------------------
2307// Store Inv
2308
2309 // Same as evict_inv_e but with cpq_evict deasserted
2310 assign store_inv_e = `SPC2.lsu.cic_invalidate_e &
2311 (`SPC2.lsu.cic_inv_wen_e!=0)&
2312 ~`SPC2.lsu.cic.cpq_evict &
2313 ~`SPC2.lsu.cic.cid_set_inval &
2314 ~`SPC2.lsu.cic.cic_xinval_e &
2315 ~(`SPC2.lsu.cic.cid_pkt_type[4:0] == 5'b10110);
2316 assign stinv_tnum_e =
2317 {`SPC2.lsu.cid.cpq_data_out[`CPX_VACK_CID],
2318 `SPC2.lsu.cid.cid_tid};
2319
2320//---------------------
2321// Store Update
2322
2323 assign store_update_e = `SPC2.lsu.cic_st_update_e;
2324 assign stu_tid_e = `SPC2.lsu.cid.cid_tid;
2325 assign stu_tnum_e = {mycid,stu_tid_e};
2326
2327 assign l1_index = {`SPC2.lsu.cid.cpq_data_out[116],
2328 `SPC2.lsu.cid.cpq_data_out[115],
2329 `SPC2.lsu.cid.cpq_data_out[114],
2330 `SPC2.lsu.cid.cpq_data_out[113],
2331 `SPC2.lsu.cid.cpq_data_out[112],
2332 `SPC2.lsu.cid.cpq_data_out[122],
2333 `SPC2.lsu.cid.cpq_data_out[121]
2334 };
2335 assign l1_way_select = `SPC2.lsu.cid_inv_vec[17:16];
2336
2337//---------------------
2338// EvictInv
2339
2340 // Same as store_inv_e but with cpq_evict asserted
2341 // LSU can invalidate 1-4 Dcache lines
2342 assign evict_inv_e[3:0] = {4{`SPC2.lsu.cic_invalidate_e & // enable for 4 bit wen below
2343 (`SPC2.lsu.cic_inv_wen_e!=0)&
2344 `SPC2.lsu.cic.cpq_evict &
2345 ~`SPC2.lsu.cic.cid_set_inval &
2346 ~`SPC2.lsu.cic.cic_xinval_e}} &
2347
2348 {|(`SPC2.lsu.cic.evict_inv_wen[15:12]), // 4 bit field - 1 hot. Send evinv when any one set.
2349 |(`SPC2.lsu.cic.evict_inv_wen[11:8]),
2350 |(`SPC2.lsu.cic.evict_inv_wen[7:4]),
2351 |(`SPC2.lsu.cic.evict_inv_wen[3:0])
2352 };
2353
2354 assign evict_srcid_e = `SPC2.lsu.cid.cpq_data_out[114:112];
2355
2356
2357//---------------------
2358// Detect Store to IO ASI in PCX crossbar packet.
2359// This causes next Store Ack to be suppressed.
2360
2361// Normal Store only since atomics are always to cacheable space
2362
2363// Trigger on Store to crossbar.
2364// If Store request is retried on crossbar (due to no grant),
2365// then, st_io_asi will fire multiple times for the same request.
2366// This is OK because it just causes sta_suppress to be set multiple times.
2367
2368 assign pcx_req = `SPC2.spc_pcx_req_pq;
2369 assign pcx_data = `SPC2.spc_pcx_data_pa;
2370
2371 assign st_io_asi = (pcx_req_1 != 9'b0) &
2372 (pcx_data [`PCX_VALID]==1'b1) &
2373 (pcx_data [`PCX_RQTYP]==`CCX_REQ_ST) &
2374 (pcx_data [103:96]==`IO_ASI_ADDR); // Upper byte of 40 bit addr
2375
2376 assign st_io_tid = pcx_data [`PCX_TID];
2377
2378 assign stb_state0_m = `SPC2.lsu.sbs0.stb_state_vld[7:0];
2379 assign stb_state1_m = `SPC2.lsu.sbs1.stb_state_vld[7:0];
2380 assign stb_state2_m = `SPC2.lsu.sbs2.stb_state_vld[7:0];
2381 assign stb_state3_m = `SPC2.lsu.sbs3.stb_state_vld[7:0];
2382 assign stb_state4_m = `SPC2.lsu.sbs4.stb_state_vld[7:0];
2383 assign stb_state5_m = `SPC2.lsu.sbs5.stb_state_vld[7:0];
2384 assign stb_state6_m = `SPC2.lsu.sbs6.stb_state_vld[7:0];
2385 assign stb_state7_m = `SPC2.lsu.sbs7.stb_state_vld[7:0];
2386
2387//---------------------
2388// Load Data (hit only) (See ldst_l2.v for Load Data - miss)
2389
2390 assign load_data_hit = load_w && (hit_w | fraw_w);
2391 assign ld_miss_b = `SPC2.lsu.dcc.dcc_ld_miss_b;
2392 assign fraw_w = `SPC2.lsu.lmc.ld_raw_bypass_w;
2393 assign hit_w = ~ld_miss_w & ~stb_hit_w;
2394 assign miss_w = ~fraw_w & (ld_miss_w | stb_hit_w);
2395
2396//---------------------
2397// Load Pop
2398
2399 assign perfmon_g = `SPC2.lsu.lsu_perfmon_trap_g;
2400 assign perfmon_tid_g = `SPC2.lsu.lsu_dcerr_tid_g;
2401 // perfmon_mask will not fire if trap is not enabled or higher priority trap is taken.
2402 assign perfmon_mask_g = {`SPC2.tlu.fls1.pil_mask_15[3:0], `SPC2.tlu.fls0.pil_mask_15[3:0]} &
2403 ~{8 {`SPC2.lsu_dcl2u_err_g | `SPC2.lsu_dcl2nd_err_g}};
2404
2405 assign perfmon = perfmon_w;
2406 assign perfmon_tid = perfmon_tid_w;
2407 assign perfmon_tnum = {mycid,perfmon_tid_w};
2408 assign perfmon_mask = perfmon_mask_w;
2409
2410
2411
2412//---------------------
2413// Store Pop
2414
2415 assign bst_kill = {`SPC2.lsu.sbs7.bst_kill,
2416 `SPC2.lsu.sbs6.bst_kill,
2417 `SPC2.lsu.sbs5.bst_kill,
2418 `SPC2.lsu.sbs4.bst_kill,
2419 `SPC2.lsu.sbs3.bst_kill,
2420 `SPC2.lsu.sbs2.bst_kill,
2421 `SPC2.lsu.sbs1.bst_kill,
2422 `SPC2.lsu.sbs0.bst_kill};
2423
2424//----------------------------------------------------------
2425//----------------------------------------------------------
2426
2427always @ (posedge `SPC2.l2clk) begin // {
2428
2429 tstamp = `TOP.core_cycle_cnt - 1;
2430
2431 //------------------------------
2432 // Pipeline from B to W
2433
2434 ldi_pa_w <= ldi_pa_b;
2435 ld_miss_w <= ld_miss_b;
2436 stb_hit_w <= `SPC2.lsu.stb_cam_hit;
2437 ldi_pf_w <= ldi_pf_b;
2438 ldi_size_w <= ldi_size_b;
2439 load_fill_m <= load_fill_e;
2440 load_fill_b <= load_fill_m;
2441 load_fill_w <= load_fill_b;
2442 ldf_tid_m <= ldf_tid_e;
2443 ldf_tid_b <= ldf_tid_m;
2444 ldf_tid_w <= ldf_tid_b;
2445 ldf_pa_m <= ldf_pa_e;
2446 ldf_pa_b <= ldf_pa_m;
2447 ldf_pa_w <= ldf_pa_b;
2448
2449 sti_size_b <= sti_size_m;
2450 sti_size_w <= (flip_size_b) ? {sti_size_b[0],sti_size_b[1],sti_size_b[2],sti_size_b[3],
2451 sti_size_b[4],sti_size_b[5],sti_size_b[6],sti_size_b[7]}
2452 : sti_size_b;
2453 sti_pa_w <= sti_pa_b;
2454 sti_tid_w <= sti_tid_b;
2455 st_ack_no_asi_m <= st_ack_no_asi_e;
2456 st_ack_no_asi_b <= st_ack_no_asi_m;
2457 st_data_access_m <= st_data_access_e;
2458 st_data_access_b <= st_data_access_m;
2459 st_data_access_w <= st_data_access_b;
2460 store_ack_w <= store_ack_b;
2461 store_update_m <= store_update_e;
2462 store_update_b <= store_update_m;
2463 store_update_w <= store_update_b;
2464 store_inv_m <= store_inv_e;
2465 store_inv_b <= store_inv_m;
2466 store_inv_w <= store_inv_b;
2467 stinv_tnum_m <= stinv_tnum_e;
2468 stinv_tnum_b <= stinv_tnum_m;
2469 stinv_tnum_w <= stinv_tnum_b;
2470 st_ack_rmo_w <= st_ack_rmo_b;
2471 stu_tid_m <= stu_tid_e;
2472 stu_tid_b <= stu_tid_m;
2473 stu_tid_w <= stu_tid_b;
2474 stu_tnum_m <= stu_tnum_e;
2475 stu_tnum_b <= stu_tnum_m;
2476 stu_tnum_w <= stu_tnum_b;
2477 store_pa_b <= store_pa_m;
2478 store_pa_w <= store_pa_b;
2479 bst_in_prog_w <= bst_in_prog_b;
2480 blk_inst_w <= blk_inst_b;
2481 sbd_st_data_w <= sbd_st_data_b;
2482 evict_inv_m <= evict_inv_e;
2483 evict_inv_b <= evict_inv_m;
2484 evict_inv_w <= evict_inv_b;
2485 evict_srcid_m <= evict_srcid_e;
2486 evict_srcid_b <= evict_srcid_m;
2487 evict_srcid_w <= evict_srcid_b;
2488 pcx_req_1 <= pcx_req;
2489 stb_state0_b <= stb_state0_m;
2490 stb_state1_b <= stb_state1_m;
2491 stb_state2_b <= stb_state2_m;
2492 stb_state3_b <= stb_state3_m;
2493 stb_state4_b <= stb_state4_m;
2494 stb_state5_b <= stb_state5_m;
2495 stb_state6_b <= stb_state6_m;
2496 stb_state7_b <= stb_state7_m;
2497 stb_state0_w <= stb_state0_b;
2498 stb_state1_w <= stb_state1_b;
2499 stb_state2_w <= stb_state2_b;
2500 stb_state3_w <= stb_state3_b;
2501 stb_state4_w <= stb_state4_b;
2502 stb_state5_w <= stb_state5_b;
2503 stb_state6_w <= stb_state6_b;
2504 stb_state7_w <= stb_state7_b;
2505
2506 perfmon_m <= perfmon_g;
2507 perfmon_b <= perfmon_m;
2508 perfmon_w <= perfmon_b;
2509 perfmon_tid_m <= perfmon_tid_g;
2510 perfmon_tid_b <= perfmon_tid_m;
2511 perfmon_tid_w <= perfmon_tid_b;
2512 perfmon_mask_m <= perfmon_mask_g;
2513 perfmon_mask_b <= perfmon_mask_m;
2514 perfmon_mask_w <= perfmon_mask_b;
2515
2516 //----------------------------------------------------------
2517 // Calculate pa for STUPDATE and STINV
2518 // Moved this into the always block to avoid the constant
2519 // probing of the dtag memory structure.
2520
2521 if (store_inv_e | store_update_e) begin // {
2522 store_pa_m[2:0] <= 3'b000;
2523 store_pa_m[10:3] <= {`SPC2.lsu.cid.cpq_data_out[116],
2524 `SPC2.lsu.cid.cpq_data_out[115],
2525 `SPC2.lsu.cid.cpq_data_out[114],
2526 `SPC2.lsu.cid.cpq_data_out[113],
2527 `SPC2.lsu.cid.cpq_data_out[112],
2528 `SPC2.lsu.cid.cpq_data_out[122],
2529 `SPC2.lsu.cid.cpq_data_out[121],
2530 `SPC2.lsu.cid.cpq_data_out[104]
2531 };
2532 store_pa_m[38:11] <= (l1_way_select==2'h0) ? dta_way0[l1_index] :
2533 (l1_way_select==2'h1) ? dta_way1[l1_index] :
2534 (l1_way_select==2'h2) ? dta_way2[l1_index] : dta_way3[l1_index];
2535 store_pa_m[39] <= 1'b0; // Only memory stores get inv/update
2536 end // }
2537
2538
2539 // After Store to IO ASI is detected at StI time, suppress the next Store Ack
2540 // There is only 1 store to IO ASI active at one time per thread because
2541 // that is all the LSU allows.
2542 if (st_io_asi) begin
2543 sta_suppress [st_io_tid] <= 1'b1;
2544 end
2545
2546 case ({ldi_atomic_b,ldi_bld_b,ldi_ldd_b,ldi_qld_b,ldi_pf_b})
2547 5'b00000: ldi_itype_w <= `ITYPE_LOAD;
2548 5'b00001: ldi_itype_w <= `ITYPE_PREFETCH;
2549 5'b00010: ldi_itype_w <= `ITYPE_QUAD_LOAD;
2550 5'b00100: ldi_itype_w <= `ITYPE_DOUBLE_LOAD;
2551 5'b01000: ldi_itype_w <= `ITYPE_BLOCK_LOAD;
2552 5'b10000: ldi_itype_w <= `ITYPE_ATOMIC;
2553 default: ldi_itype_w <= `ITYPE_NO; // Illegal
2554 endcase
2555
2556 case ({atomic_b,rmo_st_b,bst_in_prog_b})
2557 3'b000: itype_w <= `ITYPE_STORE;
2558 3'b010: itype_w <= `ITYPE_BLK_INIT_ST;
2559 3'b011: itype_w <= `ITYPE_BLOCK_STORE;
2560 3'b100: itype_w <= `ITYPE_ATOMIC;
2561 3'b001,
2562 3'b101,
2563 3'b110,
2564 3'b111: itype_w <= `ITYPE_NO; // Illegal
2565 endcase
2566
2567 //----------------------------------------------------------
2568 //----------------------------------------------------------
2569 // Load Issue
2570
2571 // Load Issue must be before Store Issue for atomic
2572
2573 if (load_w) begin // {
2574
2575 if (ldi_suppress==1'b0) begin // {
2576 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
2577 `PR_INFO ("pli_ldst", `INFO,
2578 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h size=%h typ=%0h ts=%0d",
2579 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
2580 junk = $sim_send(`PLI_MEM_LD_ISSUE,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
2581 end // }
2582 end // }
2583 else begin // {
2584 `PR_INFO ("pli_ldst", `INFO,
2585 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h Suppress for IO ASI",mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w);
2586 end // }
2587
2588 if (`PARGS.show_memop_on) begin // {
2589 `PR_NORMAL ("pli_ldst", `NORMAL,
2590 "C%0d T%0d MEMOP_LOAD tid=%d pa=%h ts=%0d (LSU - W stage)",
2591 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,tstamp);
2592 end // }
2593
2594 end // }
2595
2596 //----------------------------------------------------------
2597 //----------------------------------------------------------
2598 // Load Data (hit only) (See ldst_l2.v for Load Data - miss)
2599
2600 if (load_data_hit) begin // {
2601
2602 dsrc = hit_w ? `DSRC_L1 : `DSRC_STB;
2603
2604 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
2605 `PR_INFO ("pli_ldst", `INFO,
2606 "C%0d T%0d PLI_MEM_LDDATA tid=%d pa=%h dsrc=%0h ts=%0d",
2607 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
2608 junk = $sim_send(`PLI_MEM_LD_DATA,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
2609 end // }
2610
2611 end // }
2612
2613
2614 //----------------------------------------------------------
2615 //----------------------------------------------------------
2616 // Store Ack
2617 //
2618 // Store Ack cmd must be sent before Store Inv, Store Update for NAS
2619 // Store Ack & Store Update will be in the same timestamp
2620
2621 if (store_ack_w != 8'b0) begin // {
2622
2623 for (i=0; i<=7; i=i+1) begin // {
2624 if (store_ack_w[i]) begin // {
2625 sta_tid = i[2:0];
2626 sta_tnum = {mycid,sta_tid};
2627 sta_rmo = st_ack_rmo_w[i];
2628
2629 if (sta_suppress[sta_tid]==1'b0) begin // {
2630 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
2631 `PR_INFO ("pli_ldst", `INFO,
2632 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
2633 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
2634 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
2635 end // }
2636 end // }
2637
2638 else begin // {
2639
2640 // It is possible for 2 Stores it be in flight because of the delay from CPQ push & pop.
2641 // So, make sure Bench is suppressing the correct Store.
2642 case (sta_tid)
2643 3'h0: stb_state=stb_state0_w;
2644 3'h1: stb_state=stb_state1_w;
2645 3'h2: stb_state=stb_state2_w;
2646 3'h3: stb_state=stb_state3_w;
2647 3'h4: stb_state=stb_state4_w;
2648 3'h5: stb_state=stb_state5_w;
2649 3'h6: stb_state=stb_state6_w;
2650 3'h7: stb_state=stb_state7_w;
2651 default:
2652 `PR_ERROR ("pli_ldst", `ERROR,
2653 "C%0d T%0d PLI_MEM_XXX Bench Error. Should never execute case default",mycid,sta_tid);
2654 endcase
2655
2656 // If stb_state has only 1 bit asserted, then suppress the STACK. Otherwise, send the STACK.
2657 case (stb_state) // {
2658 8'b0000_0000: begin
2659 `PR_ERROR ("pli_ldst", `ERROR,
2660 "C%0d T%0d PLI_MEM_XXX Bench Error. stb_state should not be 8'b0",
2661 mycid,sta_tid);
2662 end
2663 8'b0000_0001,
2664 8'b0000_0010,
2665 8'b0000_0100,
2666 8'b0000_1000,
2667 8'b0001_0000,
2668 8'b0010_0000,
2669 8'b0100_0000,
2670 8'b1000_0000: stb_last = 1'b1;
2671 default: stb_last = 1'b0;
2672 endcase // }
2673
2674 if (stb_last==1'b0) begin // {
2675 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
2676 `PR_INFO ("pli_ldst", `INFO,
2677 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
2678 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
2679 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
2680 end // }
2681 end // }
2682 else begin // {
2683 sta_suppress[sta_tid] <= 1'b0;
2684 `PR_INFO ("pli_ldst", `INFO,
2685 "C%0d T%0d PLI_MEM_STACK tid=%d Suppress for IO ASI",mycid,sta_tid,sta_tnum);
2686 end // }
2687 end // }
2688
2689 end // if (store_ack_w[i]) }
2690 end // for }
2691
2692 end // if (store_ack_w) }
2693
2694 //----------------------------------------------------------
2695 //----------------------------------------------------------
2696 // Store Inv
2697
2698 if (store_inv_w) begin // {
2699
2700 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stinv_tnum_w]) begin // {
2701 `PR_INFO ("pli_ldst", `INFO,
2702 "C%0d PLI_MEM_STINV tid=%d pa=%h cid=%h ts=%0d",
2703 mycid,stinv_tnum_w,store_pa_w,mycid,tstamp);
2704 junk = $sim_send(`PLI_MEM_ST_INV,mycid,stinv_tnum_w,store_pa_w,tstamp);
2705 end // }
2706
2707 end // }
2708
2709
2710 //----------------------------------------------------------
2711 //----------------------------------------------------------
2712 // Store Update
2713
2714 if (store_update_w) begin // {
2715
2716 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stu_tnum_w]) begin // {
2717 `PR_INFO ("pli_ldst", `INFO,
2718 "C%0d T%0d PLI_MEM_STUP tid=%d pa=%h ts=%0d",
2719 mycid,stu_tid_w,stu_tnum_w,store_pa_w,tstamp);
2720 junk = $sim_send(`PLI_MEM_ST_UPDATE,stu_tnum_w,store_pa_w,tstamp);
2721 end // }
2722
2723 end // }
2724
2725 //----------------------------------------------------------
2726 //----------------------------------------------------------
2727 // Load Fill
2728
2729 if (load_fill_w) begin // {
2730
2731 ldf_tnum_w = {mycid,ldf_tid_w};
2732
2733 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldf_tnum_w]) begin // {
2734 `PR_INFO ("pli_ldst", `INFO,
2735 "C%0d T%0d PLI_MEM_LDFILL tid=%d pa=%h ts=%0d",
2736 mycid,ldf_tid_w,ldf_tnum_w,ldf_pa_w,tstamp);
2737 junk = $sim_send(`PLI_MEM_LD_FILL,ldf_tnum_w,ldf_pa_w,tstamp);
2738 end // }
2739
2740 end // }
2741
2742 //----------------------------------------------------------
2743 //----------------------------------------------------------
2744 // Store Issue
2745
2746 if (store_w) begin // {
2747
2748 if (sti_suppress==1'b0) begin // {
2749 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sti_tnum_w]) begin // {
2750 `PR_INFO ("pli_ldst", `INFO,
2751 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h data=%h sz=%h typ=%0h ts=%0d",
2752 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
2753 junk = $sim_send(`PLI_MEM_ST_ISSUE,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
2754 end // }
2755
2756 end // }
2757 else begin // {
2758 `PR_INFO ("pli_ldst", `INFO,
2759 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h Suppress for IO ASI",mycid,sti_tid_w,sti_tnum_w,sti_pa_w);
2760 end // }
2761
2762 if (`PARGS.show_memop_on) begin // {
2763 `PR_NORMAL ("pli_ldst", `NORMAL,
2764 "C%0d T%0d MEMOP_STORE tid=%d pa=%h data=%h sz=%h ts=%0d (LSU - W stage)",
2765 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,tstamp);
2766 end // }
2767
2768 end // }
2769
2770 //----------------------------------------------------------
2771 //----------------------------------------------------------
2772 // EvictInv
2773 // Send 1-4 EvictInv messages per cycle - based on how many Dcache lines were invalidated.
2774
2775 for (i=0; i<=3; i=i+1) begin // {
2776 if (evict_inv_w[i]) begin // {
2777
2778 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on) begin // {
2779 `PR_INFO ("pli_ldst", `INFO,
2780 "C%0d PLI_MEM_EVINV cid=%d srcid=%0d ts=%0d",
2781 mycid,mycid,evict_srcid_w,tstamp);
2782 junk = $sim_send(`PLI_MEM_EVICT_INV,mycid,evict_srcid_w,tstamp);
2783 end // }
2784
2785 end // }
2786 end // }
2787
2788 //----------------------------------------------------------
2789 //----------------------------------------------------------
2790 // Load Pop - special case
2791
2792 // This is required in case of a performance monitor trap due to L2 miss.
2793 // In this case, the trap is not indicated until after the Load pkt returns to the LSU.
2794 // ldst_sync has already sent LDISSUE and LDDATA to Riesling. But, the Load is not executed.
2795 // Load Pop tells Riesling to pop the LDISSUE,LDDATA off of its queues.
2796
2797 if (perfmon & perfmon_mask[perfmon_tid]) begin // {
2798
2799 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[perfmon_tnum]) begin // {
2800 `PR_INFO ("pli_ldst", `INFO,
2801 "C%0d T%0d PLI_MEM_LDPOP tid=%d ts=%0d",
2802 mycid,perfmon_tid,perfmon_tnum,tstamp);
2803 junk = $sim_send(`PLI_MEM_LD_POP,perfmon_tnum);
2804 end // }
2805
2806 end // }
2807
2808 //----------------------------------------------------------
2809 //----------------------------------------------------------
2810 // Store Pop - special cases
2811
2812 // This is required in case of a FRF error trap (internal_proc_error) on a Block Store.
2813 // In this case, the trap is not indicated until after the 8 STISSUE has been sent to Riesling.
2814 // But, the Store is not executed.
2815 // Store Pop tells Riesling to pop the 8 STISSUE off of its queues.
2816
2817 if (bst_kill!==8'b0) begin // {
2818
2819 for (i=0;i<=7;i=i+1) begin
2820 if (bst_kill[i]==1'b1) begin
2821 bst_kill_tid = i;
2822 bst_kill_tnum = {mycid,bst_kill_tid};
2823
2824 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[bst_kill_tnum]) begin // {
2825 `PR_INFO ("pli_ldst", `INFO,
2826 "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
2827 mycid,bst_kill_tid,bst_kill_tnum,tstamp);
2828 junk = $sim_send(`PLI_MEM_ST_POP,bst_kill_tnum);
2829 end // }
2830 end
2831 end
2832
2833 end // }
2834
2835 //--------------------
2836 // This is required for data_access_error on atomic. In this case, Riesling only cleans up the Load,
2837 // but doesn't know it is an atomic so Riesling doesn't clean up the store in its buffers.
2838 // The STPOP tells Riesling to clear the newest Store from the buffers.
2839 // It is possible to have older Stores in-flight but not newer Stores in-flight.
2840
2841// if (st_data_access_w != 8'b0) begin // {
2842//
2843// for (i=0; i<=7; i=i+1) begin // {
2844// if (st_data_access_w[i]) begin // {
2845// tmp_tid = i[2:0];
2846// tmp_tnum = {mycid,tmp_tid};
2847//
2848// if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[tmp_tnum]) begin // {
2849// `PR_INFO ("pli_ldst", `INFO,
2850// "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
2851// mycid,tmp_tid,tmp_tnum,tstamp);
2852// junk = $sim_send(`PLI_MEM_ST_POP,tmp_tnum);
2853// end // }
2854// end // } if st_data_access[i]
2855// end // } for
2856// end // } if st_data_access
2857
2858end // always }
2859
2860//----------------------------------------------------------
2861// Need to model the D arrays to get PA's for store updates and invalidates
2862
2863always @ (negedge `SPC2.l2clk) begin // {
2864 if (`SPC2.lsu.dta.wr_way[0])
2865 dta_way0[`SPC2.lsu.dta.index_y[6:0]] <= `SPC2.lsu.dta.wrtag_y[27:0];
2866 if (`SPC2.lsu.dta.wr_way[1])
2867 dta_way1[`SPC2.lsu.dta.index_y[6:0]] <= `SPC2.lsu.dta.wrtag_y[27:0];
2868 if (`SPC2.lsu.dta.wr_way[2])
2869 dta_way2[`SPC2.lsu.dta.index_y[6:0]] <= `SPC2.lsu.dta.wrtag_y[27:0];
2870 if (`SPC2.lsu.dta.wr_way[3])
2871 dta_way3[`SPC2.lsu.dta.index_y[6:0]] <= `SPC2.lsu.dta.wrtag_y[27:0];
2872end // always }
2873
2874//----------------------------------------------------------
2875`endif
2876endmodule
2877
2878`endif
2879`ifdef CORE_3
2880
2881module ldst_lsu_c3 ();
2882`ifndef GATESIM
2883
2884// common defines
2885`include "defines.vh"
2886`include "nas.vh"
2887// PCX/CPX packet defines (see :/verif/env/common/vera/include)
2888`include "ccx.vri"
2889`include "cmp.vri"
2890
2891//---------------------
2892// Load Signals
2893wire load_w;
2894
2895wire ldi_suppress;
2896wire [2:0] ldi_tid_w;
2897wire [5:0] ldi_tnum_w;
2898wire [39:0] ldi_pa_b;
2899reg [39:0] ldi_pa_w;
2900wire [1:0] ldi_size_b;
2901reg [1:0] ldi_size_w;
2902wire ldi_bld_b;
2903wire ldi_qld_b;
2904wire ldi_ldbl_b;
2905wire ldi_ldd_b;
2906wire ldi_atomic_b;
2907wire ldi_pf_b;
2908reg ldi_pf_w;
2909reg [7:0] ldi_itype_w;
2910reg [7:0] dsrc;
2911
2912wire ld_miss_b;
2913reg ld_miss_w;
2914reg stb_hit_w;
2915wire fraw_w;
2916wire hit_w;
2917wire miss_w;
2918wire load_data_hit;
2919
2920wire load_fill_e;
2921reg load_fill_m;
2922reg load_fill_b;
2923reg load_fill_w;
2924wire [2:0] ldf_tid_e;
2925reg [2:0] ldf_tid_m;
2926reg [2:0] ldf_tid_b;
2927reg [2:0] ldf_tid_w;
2928reg [5:0] ldf_tnum_w;
2929wire [39:0] ldf_pa_e;
2930reg [39:0] ldf_pa_m;
2931reg [39:0] ldf_pa_b;
2932reg [39:0] ldf_pa_w;
2933
2934//---------------------
2935// Store Signals
2936wire unflushed_store_w;
2937wire store_w;
2938wire sti_suppress;
2939wire [2:0] sti_tid_b;
2940reg [2:0] sti_tid_w;
2941wire [5:0] sti_tnum_w;
2942wire [39:0] sti_pa_b;
2943reg [39:0] sti_pa_w;
2944wire [63:0] sti_data_w;
2945wire [7:0] sti_size_m;
2946reg [7:0] sti_size_b;
2947reg [7:0] sti_size_w;
2948wire [7:0] sti_itype_w;
2949reg [7:0] itype_w;
2950wire [63:0] sbd_st_data_b;
2951reg [63:0] sbd_st_data_w;
2952wire flip_size_b;
2953
2954wire atomic_b;
2955wire rmo_st_b;
2956wire blk_inst_b;
2957reg blk_inst_w;
2958
2959wire bst_in_prog_b;
2960reg bst_in_prog_w;
2961wire [39:0] bst_pa_b;
2962reg [39:0] bst_pa_w;
2963wire [2:0] bst_tid_b;
2964reg [2:0] bst_tid_w;
2965wire [39:0] st_pa_b;
2966reg [39:0] st_pa_w;
2967wire [2:0] st_tid_b;
2968reg [2:0] st_tid_w;
2969
2970wire store_inv_e;
2971reg store_inv_m;
2972reg store_inv_b;
2973reg store_inv_w;
2974wire [5:0] stinv_tnum_e;
2975reg [5:0] stinv_tnum_m;
2976reg [5:0] stinv_tnum_b;
2977reg [5:0] stinv_tnum_w;
2978
2979wire store_update_e;
2980reg store_update_m;
2981reg store_update_b;
2982reg store_update_w;
2983wire [2:0] stu_tid_e;
2984reg [2:0] stu_tid_m;
2985reg [2:0] stu_tid_b;
2986reg [2:0] stu_tid_w;
2987wire [5:0] stu_tnum_e;
2988reg [5:0] stu_tnum_m;
2989reg [5:0] stu_tnum_b;
2990reg [5:0] stu_tnum_w;
2991
2992wire [7:0] asi_st_dequeue;
2993wire [7:0] st_ack_no_asi_e;
2994reg [7:0] st_ack_no_asi_m;
2995reg [7:0] st_ack_no_asi_b;
2996wire [7:0] store_ack_b;
2997reg [7:0] store_ack_w;
2998wire [7:0] st_ack_rmo_b;
2999reg [7:0] st_ack_rmo_w;
3000reg sta_rmo;
3001reg [2:0] sta_tid;
3002reg [5:0] sta_tnum;
3003reg sta_suppress [0:7]; // 1 per thread
3004wire st_io_asi;
3005wire [2:0] st_io_tid;
3006wire [7:0] st_data_access_e;
3007reg [7:0] st_data_access_m;
3008reg [7:0] st_data_access_b;
3009reg [7:0] st_data_access_w;
3010reg [2:0] tmp_tid;
3011reg [5:0] tmp_tnum;
3012
3013reg [39:0] store_pa_m;
3014reg [39:0] store_pa_b;
3015reg [39:0] store_pa_w;
3016
3017wire [1:0] l1_way_select;
3018wire [6:0] l1_index;
3019wire [27:0] my_way;
3020wire [27:0] way0;
3021wire [27:0] way1;
3022wire [27:0] way2;
3023wire [27:0] way3;
3024
3025wire [3:0] evict_inv_e;
3026reg [3:0] evict_inv_m;
3027reg [3:0] evict_inv_b;
3028reg [3:0] evict_inv_w;
3029wire [2:0] evict_srcid_e;
3030reg [2:0] evict_srcid_m;
3031reg [2:0] evict_srcid_b;
3032reg [2:0] evict_srcid_w;
3033
3034wire [8:0] pcx_req;
3035reg [8:0] pcx_req_1;
3036wire [129:0] pcx_data;
3037
3038wire perfmon;
3039wire perfmon_g;
3040reg perfmon_m;
3041reg perfmon_b;
3042reg perfmon_w;
3043wire [2:0] perfmon_tid;
3044wire [2:0] perfmon_tid_g;
3045reg [2:0] perfmon_tid_m;
3046reg [2:0] perfmon_tid_b;
3047reg [2:0] perfmon_tid_w;
3048wire [5:0] perfmon_tnum;
3049wire [7:0] perfmon_mask;
3050wire [7:0] perfmon_mask_g;
3051reg [7:0] perfmon_mask_m;
3052reg [7:0] perfmon_mask_b;
3053reg [7:0] perfmon_mask_w;
3054
3055wire [7:0] bst_kill;
3056reg [2:0] bst_kill_tid;
3057reg [5:0] bst_kill_tnum;
3058
3059wire [7:0] stb_state0_m;
3060wire [7:0] stb_state1_m;
3061wire [7:0] stb_state2_m;
3062wire [7:0] stb_state3_m;
3063wire [7:0] stb_state4_m;
3064wire [7:0] stb_state5_m;
3065wire [7:0] stb_state6_m;
3066wire [7:0] stb_state7_m;
3067reg [7:0] stb_state0_b;
3068reg [7:0] stb_state1_b;
3069reg [7:0] stb_state2_b;
3070reg [7:0] stb_state3_b;
3071reg [7:0] stb_state4_b;
3072reg [7:0] stb_state5_b;
3073reg [7:0] stb_state6_b;
3074reg [7:0] stb_state7_b;
3075reg [7:0] stb_state0_w;
3076reg [7:0] stb_state1_w;
3077reg [7:0] stb_state2_w;
3078reg [7:0] stb_state3_w;
3079reg [7:0] stb_state4_w;
3080reg [7:0] stb_state5_w;
3081reg [7:0] stb_state6_w;
3082reg [7:0] stb_state7_w;
3083reg [7:0] stb_state;
3084reg stb_last;
3085
3086// Copy of dtag
3087reg [27:0] dta_way0 [127:0];
3088reg [27:0] dta_way1 [127:0];
3089reg [27:0] dta_way2 [127:0];
3090reg [27:0] dta_way3 [127:0];
3091
3092//---------------------
3093// Misc Signals
3094wire [2:0] mycid;
3095integer tstamp;
3096integer junk;
3097integer i;
3098
3099initial begin // {
3100 ldf_tnum_w = 6'b0;
3101 dsrc = 2'b0;
3102 sta_tid = 3'b0;
3103 sta_tnum = 6'b0;
3104 for (i=0; i<=7; i=i+1) begin
3105 sta_suppress[i] = 1'b0;
3106 end
3107
3108end // }
3109
3110// for debug only - allows display in Debussy
3111wire sta_suppress0;
3112wire sta_suppress1;
3113wire sta_suppress2;
3114wire sta_suppress3;
3115wire sta_suppress4;
3116wire sta_suppress5;
3117wire sta_suppress6;
3118wire sta_suppress7;
3119
3120 assign sta_suppress0 = sta_suppress[0];
3121 assign sta_suppress1 = sta_suppress[1];
3122 assign sta_suppress2 = sta_suppress[2];
3123 assign sta_suppress3 = sta_suppress[3];
3124 assign sta_suppress4 = sta_suppress[4];
3125 assign sta_suppress5 = sta_suppress[5];
3126 assign sta_suppress6 = sta_suppress[6];
3127 assign sta_suppress7 = sta_suppress[7];
3128
3129//----------------------------------------------------------
3130//----------------------------------------------------------
3131// DUT probes
3132
3133 assign mycid = 3;
3134
3135//---------------------
3136// Load Issue
3137
3138 // If Load to IO ASIs, load issue should not be sent.
3139 // In this case, asi_internal_w is asserted and will suppress load_w.
3140
3141 assign load_w = `SPC3.lsu.dcc.ld_inst_vld_w &
3142 ~`PROBES3.asi_internal_w &
3143 ~`SPC3.lsu.dcc.flush_w &
3144 ~ldi_pf_w;
3145
3146 // ldxa to IO ASI are already suppressed since load_w will not assert.
3147 // ldi_suppress is required to also suppress normal ld to IO ASI address range.
3148 assign ldi_suppress = (ldi_pa_w[39:32] == `IO_ASI_ADDR);
3149
3150 assign ldi_tid_w = `SPC3.lsu.dcc.tid_w;
3151 assign ldi_tnum_w = {mycid,ldi_tid_w};
3152 assign ldi_size_b = `SPC3.lsu.dcc.ldst_sz_b; // 2 bits
3153 assign ldi_atomic_b = `SPC3.lsu.dcc.atomic_b;
3154 assign ldi_qld_b = `SPC3.lsu.dcc.quad_ldd_b;
3155 assign ldi_ldbl_b = `SPC3.lsu.dcc_ldbl_b;
3156 assign ldi_ldd_b = ldi_ldbl_b & !ldi_qld_b;
3157 assign ldi_bld_b = `SPC3.lsu.dcc.dcc_blk_inst_b;
3158 assign ldi_pf_b = `SPC3.lsu.dcc.pref_inst_b;
3159
3160 // pa, tid are same for LoadIssue and StoreIssue
3161 assign ldi_pa_b = {`SPC3.lsu.tlb_pgnum[39:13],
3162 `SPC3.lsu.lmd.lsu_va_b[12:0]};
3163
3164//---------------------
3165// Load Fill
3166
3167 assign load_fill_e = `SPC3.lsu.dcc.ld_fill_e;
3168 assign ldf_tid_e = `SPC3.lsu.cid.cid_tid;
3169 assign ldf_pa_e = {`SPC3.lsu.lmd.lmd_fill_addr_e[39:3],3'b0};
3170
3171//---------------------
3172// Store Issue
3173
3174 // blk_inst_w will suppress store_w for 1st of 9 cycles on block store.
3175
3176 // If Store to IO ASIs, store issue should not be sent.
3177 // In this case, asi_internal_w is asserted and will suppress store_w.
3178
3179 assign unflushed_store_w = `SPC3.lsu.sbc.unflushed_store_w;
3180
3181 assign store_w = unflushed_store_w &
3182 (~(`PROBES3.asi_internal_w | blk_inst_w) |
3183 bst_in_prog_w);
3184
3185 assign atomic_b = `SPC3.lsu.dcc.atomic_b;
3186 assign rmo_st_b = `SPC3.lsu.sbc_rmo_st_b;
3187 assign blk_inst_b = `SPC3.lsu.dcc.dcc_blk_inst_b;
3188
3189 assign sti_tnum_w = {mycid,sti_tid_w};
3190 assign sti_size_m = `SPC3.lsu.dcc_ldst_bmask;
3191
3192 // flip_size will assert if endian swap for partial store is needed
3193 assign flip_size_b = `SPC3.lsu.dcc.pst_asi_b & `SPC3.lsu.dcc.tlb_tte_ie_b & `SPC3.lsu.dcc.tlb_tte_vld_b & `SPC3.lsu.dcc.st_inst_vld_b;
3194
3195 // Change itype only when control signals are valid
3196 assign sti_itype_w = unflushed_store_w ? itype_w : sti_itype_w;
3197
3198 // It is correct to mix W & B stage signals for this.
3199 // STD is a 2 cycle instruction.
3200 // inst valid in W, data in B (1 cycle behind)
3201 assign sti_data_w = `SPC3.lsu.sbc.std_inst_w ?
3202 sbd_st_data_b :
3203 sbd_st_data_w;
3204 assign sbd_st_data_b = `SPC3.lsu.sbd_st_data_b;
3205
3206 // Use different pa,tid if block store
3207 assign sti_pa_b = bst_in_prog_b ? bst_pa_b : st_pa_b;
3208 assign sti_tid_b = bst_in_prog_b ? bst_tid_b : st_tid_b;
3209
3210 // stxa to IO ASI are already suppressed since store_w will not assert.
3211 // sti_suppress is required to also suppress normal st to IO ASI address range.
3212 assign sti_suppress = (sti_pa_w[39:32] == `IO_ASI_ADDR);
3213
3214 // Normal Store
3215 assign st_pa_b = {`SPC3.lsu.tlb_pgnum[39:13],
3216 `SPC3.lsu.lmd.lsu_va_b[12:0]};
3217 assign st_tid_b = `SPC3.lsu.dcc.tid_b;
3218
3219 // Block Store
3220 assign bst_in_prog_b = `SPC3.lsu.sbc.bst_in_prog_b;
3221 assign bst_pa_b = {`SPC3.lsu.sbd.st_addr_b[39:3],3'b0};
3222 assign bst_tid_b = `SPC3.lsu.sbc.bst_tid;
3223
3224//---------------------
3225// Store Ack
3226
3227assign asi_st_dequeue[7:0] = `SPC3.lsu.dcc_asi_rtn_vld[7:0] &
3228 {8{~`SPC3.lsu.dcc_asi_rtn_rd}};
3229
3230 assign st_ack_no_asi_e = `SPC3.lsu.cic.cic_st_dequeue[7:0] &
3231 ~asi_st_dequeue[7:0] &
3232 ~`SPC3.lsu.cic.sbc_bst_sel[7:0];
3233
3234 assign st_ack_rmo_b = {`SPC3.lsu.sbs7.rmo_st_commit_p4,
3235 `SPC3.lsu.sbs6.rmo_st_commit_p4,
3236 `SPC3.lsu.sbs5.rmo_st_commit_p4,
3237 `SPC3.lsu.sbs4.rmo_st_commit_p4,
3238 `SPC3.lsu.sbs3.rmo_st_commit_p4,
3239 `SPC3.lsu.sbs2.rmo_st_commit_p4,
3240 `SPC3.lsu.sbs1.rmo_st_commit_p4,
3241 `SPC3.lsu.sbs0.rmo_st_commit_p4
3242 };
3243
3244 // It is possible to see 2 threads store_ack in same cycle
3245 // (1 st_ack_no_asi & 1 st_ack_rmo)
3246
3247 assign store_ack_b = st_ack_no_asi_b | st_ack_rmo_b;
3248
3249 // cic_st_atm_cmplt is atomic store completing (same time as store ack)
3250 // (lsu.lmc.dcl2u_err | dcl2nd_err) indicate a data_access_error condition
3251 assign st_data_access_e = {8{(`SPC3.lsu.cic.cic_st_atm_cmplt &
3252 (`SPC3.lsu.lmc.dcl2u_err | `SPC3.lsu.lmc.dcl2nd_err))}} &
3253 `SPC3.lsu.cic.cic_st_dequeue[7:0];
3254//---------------------
3255// Store Inv
3256
3257 // Same as evict_inv_e but with cpq_evict deasserted
3258 assign store_inv_e = `SPC3.lsu.cic_invalidate_e &
3259 (`SPC3.lsu.cic_inv_wen_e!=0)&
3260 ~`SPC3.lsu.cic.cpq_evict &
3261 ~`SPC3.lsu.cic.cid_set_inval &
3262 ~`SPC3.lsu.cic.cic_xinval_e &
3263 ~(`SPC3.lsu.cic.cid_pkt_type[4:0] == 5'b10110);
3264 assign stinv_tnum_e =
3265 {`SPC3.lsu.cid.cpq_data_out[`CPX_VACK_CID],
3266 `SPC3.lsu.cid.cid_tid};
3267
3268//---------------------
3269// Store Update
3270
3271 assign store_update_e = `SPC3.lsu.cic_st_update_e;
3272 assign stu_tid_e = `SPC3.lsu.cid.cid_tid;
3273 assign stu_tnum_e = {mycid,stu_tid_e};
3274
3275 assign l1_index = {`SPC3.lsu.cid.cpq_data_out[116],
3276 `SPC3.lsu.cid.cpq_data_out[115],
3277 `SPC3.lsu.cid.cpq_data_out[114],
3278 `SPC3.lsu.cid.cpq_data_out[113],
3279 `SPC3.lsu.cid.cpq_data_out[112],
3280 `SPC3.lsu.cid.cpq_data_out[122],
3281 `SPC3.lsu.cid.cpq_data_out[121]
3282 };
3283 assign l1_way_select = `SPC3.lsu.cid_inv_vec[17:16];
3284
3285//---------------------
3286// EvictInv
3287
3288 // Same as store_inv_e but with cpq_evict asserted
3289 // LSU can invalidate 1-4 Dcache lines
3290 assign evict_inv_e[3:0] = {4{`SPC3.lsu.cic_invalidate_e & // enable for 4 bit wen below
3291 (`SPC3.lsu.cic_inv_wen_e!=0)&
3292 `SPC3.lsu.cic.cpq_evict &
3293 ~`SPC3.lsu.cic.cid_set_inval &
3294 ~`SPC3.lsu.cic.cic_xinval_e}} &
3295
3296 {|(`SPC3.lsu.cic.evict_inv_wen[15:12]), // 4 bit field - 1 hot. Send evinv when any one set.
3297 |(`SPC3.lsu.cic.evict_inv_wen[11:8]),
3298 |(`SPC3.lsu.cic.evict_inv_wen[7:4]),
3299 |(`SPC3.lsu.cic.evict_inv_wen[3:0])
3300 };
3301
3302 assign evict_srcid_e = `SPC3.lsu.cid.cpq_data_out[114:112];
3303
3304
3305//---------------------
3306// Detect Store to IO ASI in PCX crossbar packet.
3307// This causes next Store Ack to be suppressed.
3308
3309// Normal Store only since atomics are always to cacheable space
3310
3311// Trigger on Store to crossbar.
3312// If Store request is retried on crossbar (due to no grant),
3313// then, st_io_asi will fire multiple times for the same request.
3314// This is OK because it just causes sta_suppress to be set multiple times.
3315
3316 assign pcx_req = `SPC3.spc_pcx_req_pq;
3317 assign pcx_data = `SPC3.spc_pcx_data_pa;
3318
3319 assign st_io_asi = (pcx_req_1 != 9'b0) &
3320 (pcx_data [`PCX_VALID]==1'b1) &
3321 (pcx_data [`PCX_RQTYP]==`CCX_REQ_ST) &
3322 (pcx_data [103:96]==`IO_ASI_ADDR); // Upper byte of 40 bit addr
3323
3324 assign st_io_tid = pcx_data [`PCX_TID];
3325
3326 assign stb_state0_m = `SPC3.lsu.sbs0.stb_state_vld[7:0];
3327 assign stb_state1_m = `SPC3.lsu.sbs1.stb_state_vld[7:0];
3328 assign stb_state2_m = `SPC3.lsu.sbs2.stb_state_vld[7:0];
3329 assign stb_state3_m = `SPC3.lsu.sbs3.stb_state_vld[7:0];
3330 assign stb_state4_m = `SPC3.lsu.sbs4.stb_state_vld[7:0];
3331 assign stb_state5_m = `SPC3.lsu.sbs5.stb_state_vld[7:0];
3332 assign stb_state6_m = `SPC3.lsu.sbs6.stb_state_vld[7:0];
3333 assign stb_state7_m = `SPC3.lsu.sbs7.stb_state_vld[7:0];
3334
3335//---------------------
3336// Load Data (hit only) (See ldst_l2.v for Load Data - miss)
3337
3338 assign load_data_hit = load_w && (hit_w | fraw_w);
3339 assign ld_miss_b = `SPC3.lsu.dcc.dcc_ld_miss_b;
3340 assign fraw_w = `SPC3.lsu.lmc.ld_raw_bypass_w;
3341 assign hit_w = ~ld_miss_w & ~stb_hit_w;
3342 assign miss_w = ~fraw_w & (ld_miss_w | stb_hit_w);
3343
3344//---------------------
3345// Load Pop
3346
3347 assign perfmon_g = `SPC3.lsu.lsu_perfmon_trap_g;
3348 assign perfmon_tid_g = `SPC3.lsu.lsu_dcerr_tid_g;
3349 // perfmon_mask will not fire if trap is not enabled or higher priority trap is taken.
3350 assign perfmon_mask_g = {`SPC3.tlu.fls1.pil_mask_15[3:0], `SPC3.tlu.fls0.pil_mask_15[3:0]} &
3351 ~{8 {`SPC3.lsu_dcl2u_err_g | `SPC3.lsu_dcl2nd_err_g}};
3352
3353 assign perfmon = perfmon_w;
3354 assign perfmon_tid = perfmon_tid_w;
3355 assign perfmon_tnum = {mycid,perfmon_tid_w};
3356 assign perfmon_mask = perfmon_mask_w;
3357
3358
3359
3360//---------------------
3361// Store Pop
3362
3363 assign bst_kill = {`SPC3.lsu.sbs7.bst_kill,
3364 `SPC3.lsu.sbs6.bst_kill,
3365 `SPC3.lsu.sbs5.bst_kill,
3366 `SPC3.lsu.sbs4.bst_kill,
3367 `SPC3.lsu.sbs3.bst_kill,
3368 `SPC3.lsu.sbs2.bst_kill,
3369 `SPC3.lsu.sbs1.bst_kill,
3370 `SPC3.lsu.sbs0.bst_kill};
3371
3372//----------------------------------------------------------
3373//----------------------------------------------------------
3374
3375always @ (posedge `SPC3.l2clk) begin // {
3376
3377 tstamp = `TOP.core_cycle_cnt - 1;
3378
3379 //------------------------------
3380 // Pipeline from B to W
3381
3382 ldi_pa_w <= ldi_pa_b;
3383 ld_miss_w <= ld_miss_b;
3384 stb_hit_w <= `SPC3.lsu.stb_cam_hit;
3385 ldi_pf_w <= ldi_pf_b;
3386 ldi_size_w <= ldi_size_b;
3387 load_fill_m <= load_fill_e;
3388 load_fill_b <= load_fill_m;
3389 load_fill_w <= load_fill_b;
3390 ldf_tid_m <= ldf_tid_e;
3391 ldf_tid_b <= ldf_tid_m;
3392 ldf_tid_w <= ldf_tid_b;
3393 ldf_pa_m <= ldf_pa_e;
3394 ldf_pa_b <= ldf_pa_m;
3395 ldf_pa_w <= ldf_pa_b;
3396
3397 sti_size_b <= sti_size_m;
3398 sti_size_w <= (flip_size_b) ? {sti_size_b[0],sti_size_b[1],sti_size_b[2],sti_size_b[3],
3399 sti_size_b[4],sti_size_b[5],sti_size_b[6],sti_size_b[7]}
3400 : sti_size_b;
3401 sti_pa_w <= sti_pa_b;
3402 sti_tid_w <= sti_tid_b;
3403 st_ack_no_asi_m <= st_ack_no_asi_e;
3404 st_ack_no_asi_b <= st_ack_no_asi_m;
3405 st_data_access_m <= st_data_access_e;
3406 st_data_access_b <= st_data_access_m;
3407 st_data_access_w <= st_data_access_b;
3408 store_ack_w <= store_ack_b;
3409 store_update_m <= store_update_e;
3410 store_update_b <= store_update_m;
3411 store_update_w <= store_update_b;
3412 store_inv_m <= store_inv_e;
3413 store_inv_b <= store_inv_m;
3414 store_inv_w <= store_inv_b;
3415 stinv_tnum_m <= stinv_tnum_e;
3416 stinv_tnum_b <= stinv_tnum_m;
3417 stinv_tnum_w <= stinv_tnum_b;
3418 st_ack_rmo_w <= st_ack_rmo_b;
3419 stu_tid_m <= stu_tid_e;
3420 stu_tid_b <= stu_tid_m;
3421 stu_tid_w <= stu_tid_b;
3422 stu_tnum_m <= stu_tnum_e;
3423 stu_tnum_b <= stu_tnum_m;
3424 stu_tnum_w <= stu_tnum_b;
3425 store_pa_b <= store_pa_m;
3426 store_pa_w <= store_pa_b;
3427 bst_in_prog_w <= bst_in_prog_b;
3428 blk_inst_w <= blk_inst_b;
3429 sbd_st_data_w <= sbd_st_data_b;
3430 evict_inv_m <= evict_inv_e;
3431 evict_inv_b <= evict_inv_m;
3432 evict_inv_w <= evict_inv_b;
3433 evict_srcid_m <= evict_srcid_e;
3434 evict_srcid_b <= evict_srcid_m;
3435 evict_srcid_w <= evict_srcid_b;
3436 pcx_req_1 <= pcx_req;
3437 stb_state0_b <= stb_state0_m;
3438 stb_state1_b <= stb_state1_m;
3439 stb_state2_b <= stb_state2_m;
3440 stb_state3_b <= stb_state3_m;
3441 stb_state4_b <= stb_state4_m;
3442 stb_state5_b <= stb_state5_m;
3443 stb_state6_b <= stb_state6_m;
3444 stb_state7_b <= stb_state7_m;
3445 stb_state0_w <= stb_state0_b;
3446 stb_state1_w <= stb_state1_b;
3447 stb_state2_w <= stb_state2_b;
3448 stb_state3_w <= stb_state3_b;
3449 stb_state4_w <= stb_state4_b;
3450 stb_state5_w <= stb_state5_b;
3451 stb_state6_w <= stb_state6_b;
3452 stb_state7_w <= stb_state7_b;
3453
3454 perfmon_m <= perfmon_g;
3455 perfmon_b <= perfmon_m;
3456 perfmon_w <= perfmon_b;
3457 perfmon_tid_m <= perfmon_tid_g;
3458 perfmon_tid_b <= perfmon_tid_m;
3459 perfmon_tid_w <= perfmon_tid_b;
3460 perfmon_mask_m <= perfmon_mask_g;
3461 perfmon_mask_b <= perfmon_mask_m;
3462 perfmon_mask_w <= perfmon_mask_b;
3463
3464 //----------------------------------------------------------
3465 // Calculate pa for STUPDATE and STINV
3466 // Moved this into the always block to avoid the constant
3467 // probing of the dtag memory structure.
3468
3469 if (store_inv_e | store_update_e) begin // {
3470 store_pa_m[2:0] <= 3'b000;
3471 store_pa_m[10:3] <= {`SPC3.lsu.cid.cpq_data_out[116],
3472 `SPC3.lsu.cid.cpq_data_out[115],
3473 `SPC3.lsu.cid.cpq_data_out[114],
3474 `SPC3.lsu.cid.cpq_data_out[113],
3475 `SPC3.lsu.cid.cpq_data_out[112],
3476 `SPC3.lsu.cid.cpq_data_out[122],
3477 `SPC3.lsu.cid.cpq_data_out[121],
3478 `SPC3.lsu.cid.cpq_data_out[104]
3479 };
3480 store_pa_m[38:11] <= (l1_way_select==2'h0) ? dta_way0[l1_index] :
3481 (l1_way_select==2'h1) ? dta_way1[l1_index] :
3482 (l1_way_select==2'h2) ? dta_way2[l1_index] : dta_way3[l1_index];
3483 store_pa_m[39] <= 1'b0; // Only memory stores get inv/update
3484 end // }
3485
3486
3487 // After Store to IO ASI is detected at StI time, suppress the next Store Ack
3488 // There is only 1 store to IO ASI active at one time per thread because
3489 // that is all the LSU allows.
3490 if (st_io_asi) begin
3491 sta_suppress [st_io_tid] <= 1'b1;
3492 end
3493
3494 case ({ldi_atomic_b,ldi_bld_b,ldi_ldd_b,ldi_qld_b,ldi_pf_b})
3495 5'b00000: ldi_itype_w <= `ITYPE_LOAD;
3496 5'b00001: ldi_itype_w <= `ITYPE_PREFETCH;
3497 5'b00010: ldi_itype_w <= `ITYPE_QUAD_LOAD;
3498 5'b00100: ldi_itype_w <= `ITYPE_DOUBLE_LOAD;
3499 5'b01000: ldi_itype_w <= `ITYPE_BLOCK_LOAD;
3500 5'b10000: ldi_itype_w <= `ITYPE_ATOMIC;
3501 default: ldi_itype_w <= `ITYPE_NO; // Illegal
3502 endcase
3503
3504 case ({atomic_b,rmo_st_b,bst_in_prog_b})
3505 3'b000: itype_w <= `ITYPE_STORE;
3506 3'b010: itype_w <= `ITYPE_BLK_INIT_ST;
3507 3'b011: itype_w <= `ITYPE_BLOCK_STORE;
3508 3'b100: itype_w <= `ITYPE_ATOMIC;
3509 3'b001,
3510 3'b101,
3511 3'b110,
3512 3'b111: itype_w <= `ITYPE_NO; // Illegal
3513 endcase
3514
3515 //----------------------------------------------------------
3516 //----------------------------------------------------------
3517 // Load Issue
3518
3519 // Load Issue must be before Store Issue for atomic
3520
3521 if (load_w) begin // {
3522
3523 if (ldi_suppress==1'b0) begin // {
3524 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
3525 `PR_INFO ("pli_ldst", `INFO,
3526 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h size=%h typ=%0h ts=%0d",
3527 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
3528 junk = $sim_send(`PLI_MEM_LD_ISSUE,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
3529 end // }
3530 end // }
3531 else begin // {
3532 `PR_INFO ("pli_ldst", `INFO,
3533 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h Suppress for IO ASI",mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w);
3534 end // }
3535
3536 if (`PARGS.show_memop_on) begin // {
3537 `PR_NORMAL ("pli_ldst", `NORMAL,
3538 "C%0d T%0d MEMOP_LOAD tid=%d pa=%h ts=%0d (LSU - W stage)",
3539 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,tstamp);
3540 end // }
3541
3542 end // }
3543
3544 //----------------------------------------------------------
3545 //----------------------------------------------------------
3546 // Load Data (hit only) (See ldst_l2.v for Load Data - miss)
3547
3548 if (load_data_hit) begin // {
3549
3550 dsrc = hit_w ? `DSRC_L1 : `DSRC_STB;
3551
3552 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
3553 `PR_INFO ("pli_ldst", `INFO,
3554 "C%0d T%0d PLI_MEM_LDDATA tid=%d pa=%h dsrc=%0h ts=%0d",
3555 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
3556 junk = $sim_send(`PLI_MEM_LD_DATA,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
3557 end // }
3558
3559 end // }
3560
3561
3562 //----------------------------------------------------------
3563 //----------------------------------------------------------
3564 // Store Ack
3565 //
3566 // Store Ack cmd must be sent before Store Inv, Store Update for NAS
3567 // Store Ack & Store Update will be in the same timestamp
3568
3569 if (store_ack_w != 8'b0) begin // {
3570
3571 for (i=0; i<=7; i=i+1) begin // {
3572 if (store_ack_w[i]) begin // {
3573 sta_tid = i[2:0];
3574 sta_tnum = {mycid,sta_tid};
3575 sta_rmo = st_ack_rmo_w[i];
3576
3577 if (sta_suppress[sta_tid]==1'b0) begin // {
3578 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
3579 `PR_INFO ("pli_ldst", `INFO,
3580 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
3581 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
3582 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
3583 end // }
3584 end // }
3585
3586 else begin // {
3587
3588 // It is possible for 2 Stores it be in flight because of the delay from CPQ push & pop.
3589 // So, make sure Bench is suppressing the correct Store.
3590 case (sta_tid)
3591 3'h0: stb_state=stb_state0_w;
3592 3'h1: stb_state=stb_state1_w;
3593 3'h2: stb_state=stb_state2_w;
3594 3'h3: stb_state=stb_state3_w;
3595 3'h4: stb_state=stb_state4_w;
3596 3'h5: stb_state=stb_state5_w;
3597 3'h6: stb_state=stb_state6_w;
3598 3'h7: stb_state=stb_state7_w;
3599 default:
3600 `PR_ERROR ("pli_ldst", `ERROR,
3601 "C%0d T%0d PLI_MEM_XXX Bench Error. Should never execute case default",mycid,sta_tid);
3602 endcase
3603
3604 // If stb_state has only 1 bit asserted, then suppress the STACK. Otherwise, send the STACK.
3605 case (stb_state) // {
3606 8'b0000_0000: begin
3607 `PR_ERROR ("pli_ldst", `ERROR,
3608 "C%0d T%0d PLI_MEM_XXX Bench Error. stb_state should not be 8'b0",
3609 mycid,sta_tid);
3610 end
3611 8'b0000_0001,
3612 8'b0000_0010,
3613 8'b0000_0100,
3614 8'b0000_1000,
3615 8'b0001_0000,
3616 8'b0010_0000,
3617 8'b0100_0000,
3618 8'b1000_0000: stb_last = 1'b1;
3619 default: stb_last = 1'b0;
3620 endcase // }
3621
3622 if (stb_last==1'b0) begin // {
3623 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
3624 `PR_INFO ("pli_ldst", `INFO,
3625 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
3626 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
3627 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
3628 end // }
3629 end // }
3630 else begin // {
3631 sta_suppress[sta_tid] <= 1'b0;
3632 `PR_INFO ("pli_ldst", `INFO,
3633 "C%0d T%0d PLI_MEM_STACK tid=%d Suppress for IO ASI",mycid,sta_tid,sta_tnum);
3634 end // }
3635 end // }
3636
3637 end // if (store_ack_w[i]) }
3638 end // for }
3639
3640 end // if (store_ack_w) }
3641
3642 //----------------------------------------------------------
3643 //----------------------------------------------------------
3644 // Store Inv
3645
3646 if (store_inv_w) begin // {
3647
3648 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stinv_tnum_w]) begin // {
3649 `PR_INFO ("pli_ldst", `INFO,
3650 "C%0d PLI_MEM_STINV tid=%d pa=%h cid=%h ts=%0d",
3651 mycid,stinv_tnum_w,store_pa_w,mycid,tstamp);
3652 junk = $sim_send(`PLI_MEM_ST_INV,mycid,stinv_tnum_w,store_pa_w,tstamp);
3653 end // }
3654
3655 end // }
3656
3657
3658 //----------------------------------------------------------
3659 //----------------------------------------------------------
3660 // Store Update
3661
3662 if (store_update_w) begin // {
3663
3664 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stu_tnum_w]) begin // {
3665 `PR_INFO ("pli_ldst", `INFO,
3666 "C%0d T%0d PLI_MEM_STUP tid=%d pa=%h ts=%0d",
3667 mycid,stu_tid_w,stu_tnum_w,store_pa_w,tstamp);
3668 junk = $sim_send(`PLI_MEM_ST_UPDATE,stu_tnum_w,store_pa_w,tstamp);
3669 end // }
3670
3671 end // }
3672
3673 //----------------------------------------------------------
3674 //----------------------------------------------------------
3675 // Load Fill
3676
3677 if (load_fill_w) begin // {
3678
3679 ldf_tnum_w = {mycid,ldf_tid_w};
3680
3681 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldf_tnum_w]) begin // {
3682 `PR_INFO ("pli_ldst", `INFO,
3683 "C%0d T%0d PLI_MEM_LDFILL tid=%d pa=%h ts=%0d",
3684 mycid,ldf_tid_w,ldf_tnum_w,ldf_pa_w,tstamp);
3685 junk = $sim_send(`PLI_MEM_LD_FILL,ldf_tnum_w,ldf_pa_w,tstamp);
3686 end // }
3687
3688 end // }
3689
3690 //----------------------------------------------------------
3691 //----------------------------------------------------------
3692 // Store Issue
3693
3694 if (store_w) begin // {
3695
3696 if (sti_suppress==1'b0) begin // {
3697 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sti_tnum_w]) begin // {
3698 `PR_INFO ("pli_ldst", `INFO,
3699 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h data=%h sz=%h typ=%0h ts=%0d",
3700 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
3701 junk = $sim_send(`PLI_MEM_ST_ISSUE,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
3702 end // }
3703
3704 end // }
3705 else begin // {
3706 `PR_INFO ("pli_ldst", `INFO,
3707 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h Suppress for IO ASI",mycid,sti_tid_w,sti_tnum_w,sti_pa_w);
3708 end // }
3709
3710 if (`PARGS.show_memop_on) begin // {
3711 `PR_NORMAL ("pli_ldst", `NORMAL,
3712 "C%0d T%0d MEMOP_STORE tid=%d pa=%h data=%h sz=%h ts=%0d (LSU - W stage)",
3713 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,tstamp);
3714 end // }
3715
3716 end // }
3717
3718 //----------------------------------------------------------
3719 //----------------------------------------------------------
3720 // EvictInv
3721 // Send 1-4 EvictInv messages per cycle - based on how many Dcache lines were invalidated.
3722
3723 for (i=0; i<=3; i=i+1) begin // {
3724 if (evict_inv_w[i]) begin // {
3725
3726 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on) begin // {
3727 `PR_INFO ("pli_ldst", `INFO,
3728 "C%0d PLI_MEM_EVINV cid=%d srcid=%0d ts=%0d",
3729 mycid,mycid,evict_srcid_w,tstamp);
3730 junk = $sim_send(`PLI_MEM_EVICT_INV,mycid,evict_srcid_w,tstamp);
3731 end // }
3732
3733 end // }
3734 end // }
3735
3736 //----------------------------------------------------------
3737 //----------------------------------------------------------
3738 // Load Pop - special case
3739
3740 // This is required in case of a performance monitor trap due to L2 miss.
3741 // In this case, the trap is not indicated until after the Load pkt returns to the LSU.
3742 // ldst_sync has already sent LDISSUE and LDDATA to Riesling. But, the Load is not executed.
3743 // Load Pop tells Riesling to pop the LDISSUE,LDDATA off of its queues.
3744
3745 if (perfmon & perfmon_mask[perfmon_tid]) begin // {
3746
3747 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[perfmon_tnum]) begin // {
3748 `PR_INFO ("pli_ldst", `INFO,
3749 "C%0d T%0d PLI_MEM_LDPOP tid=%d ts=%0d",
3750 mycid,perfmon_tid,perfmon_tnum,tstamp);
3751 junk = $sim_send(`PLI_MEM_LD_POP,perfmon_tnum);
3752 end // }
3753
3754 end // }
3755
3756 //----------------------------------------------------------
3757 //----------------------------------------------------------
3758 // Store Pop - special cases
3759
3760 // This is required in case of a FRF error trap (internal_proc_error) on a Block Store.
3761 // In this case, the trap is not indicated until after the 8 STISSUE has been sent to Riesling.
3762 // But, the Store is not executed.
3763 // Store Pop tells Riesling to pop the 8 STISSUE off of its queues.
3764
3765 if (bst_kill!==8'b0) begin // {
3766
3767 for (i=0;i<=7;i=i+1) begin
3768 if (bst_kill[i]==1'b1) begin
3769 bst_kill_tid = i;
3770 bst_kill_tnum = {mycid,bst_kill_tid};
3771
3772 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[bst_kill_tnum]) begin // {
3773 `PR_INFO ("pli_ldst", `INFO,
3774 "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
3775 mycid,bst_kill_tid,bst_kill_tnum,tstamp);
3776 junk = $sim_send(`PLI_MEM_ST_POP,bst_kill_tnum);
3777 end // }
3778 end
3779 end
3780
3781 end // }
3782
3783 //--------------------
3784 // This is required for data_access_error on atomic. In this case, Riesling only cleans up the Load,
3785 // but doesn't know it is an atomic so Riesling doesn't clean up the store in its buffers.
3786 // The STPOP tells Riesling to clear the newest Store from the buffers.
3787 // It is possible to have older Stores in-flight but not newer Stores in-flight.
3788
3789// if (st_data_access_w != 8'b0) begin // {
3790//
3791// for (i=0; i<=7; i=i+1) begin // {
3792// if (st_data_access_w[i]) begin // {
3793// tmp_tid = i[2:0];
3794// tmp_tnum = {mycid,tmp_tid};
3795//
3796// if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[tmp_tnum]) begin // {
3797// `PR_INFO ("pli_ldst", `INFO,
3798// "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
3799// mycid,tmp_tid,tmp_tnum,tstamp);
3800// junk = $sim_send(`PLI_MEM_ST_POP,tmp_tnum);
3801// end // }
3802// end // } if st_data_access[i]
3803// end // } for
3804// end // } if st_data_access
3805
3806end // always }
3807
3808//----------------------------------------------------------
3809// Need to model the D arrays to get PA's for store updates and invalidates
3810
3811always @ (negedge `SPC3.l2clk) begin // {
3812 if (`SPC3.lsu.dta.wr_way[0])
3813 dta_way0[`SPC3.lsu.dta.index_y[6:0]] <= `SPC3.lsu.dta.wrtag_y[27:0];
3814 if (`SPC3.lsu.dta.wr_way[1])
3815 dta_way1[`SPC3.lsu.dta.index_y[6:0]] <= `SPC3.lsu.dta.wrtag_y[27:0];
3816 if (`SPC3.lsu.dta.wr_way[2])
3817 dta_way2[`SPC3.lsu.dta.index_y[6:0]] <= `SPC3.lsu.dta.wrtag_y[27:0];
3818 if (`SPC3.lsu.dta.wr_way[3])
3819 dta_way3[`SPC3.lsu.dta.index_y[6:0]] <= `SPC3.lsu.dta.wrtag_y[27:0];
3820end // always }
3821
3822//----------------------------------------------------------
3823`endif
3824endmodule
3825
3826`endif
3827`ifdef CORE_4
3828
3829module ldst_lsu_c4 ();
3830`ifndef GATESIM
3831
3832// common defines
3833`include "defines.vh"
3834`include "nas.vh"
3835// PCX/CPX packet defines (see :/verif/env/common/vera/include)
3836`include "ccx.vri"
3837`include "cmp.vri"
3838
3839//---------------------
3840// Load Signals
3841wire load_w;
3842
3843wire ldi_suppress;
3844wire [2:0] ldi_tid_w;
3845wire [5:0] ldi_tnum_w;
3846wire [39:0] ldi_pa_b;
3847reg [39:0] ldi_pa_w;
3848wire [1:0] ldi_size_b;
3849reg [1:0] ldi_size_w;
3850wire ldi_bld_b;
3851wire ldi_qld_b;
3852wire ldi_ldbl_b;
3853wire ldi_ldd_b;
3854wire ldi_atomic_b;
3855wire ldi_pf_b;
3856reg ldi_pf_w;
3857reg [7:0] ldi_itype_w;
3858reg [7:0] dsrc;
3859
3860wire ld_miss_b;
3861reg ld_miss_w;
3862reg stb_hit_w;
3863wire fraw_w;
3864wire hit_w;
3865wire miss_w;
3866wire load_data_hit;
3867
3868wire load_fill_e;
3869reg load_fill_m;
3870reg load_fill_b;
3871reg load_fill_w;
3872wire [2:0] ldf_tid_e;
3873reg [2:0] ldf_tid_m;
3874reg [2:0] ldf_tid_b;
3875reg [2:0] ldf_tid_w;
3876reg [5:0] ldf_tnum_w;
3877wire [39:0] ldf_pa_e;
3878reg [39:0] ldf_pa_m;
3879reg [39:0] ldf_pa_b;
3880reg [39:0] ldf_pa_w;
3881
3882//---------------------
3883// Store Signals
3884wire unflushed_store_w;
3885wire store_w;
3886wire sti_suppress;
3887wire [2:0] sti_tid_b;
3888reg [2:0] sti_tid_w;
3889wire [5:0] sti_tnum_w;
3890wire [39:0] sti_pa_b;
3891reg [39:0] sti_pa_w;
3892wire [63:0] sti_data_w;
3893wire [7:0] sti_size_m;
3894reg [7:0] sti_size_b;
3895reg [7:0] sti_size_w;
3896wire [7:0] sti_itype_w;
3897reg [7:0] itype_w;
3898wire [63:0] sbd_st_data_b;
3899reg [63:0] sbd_st_data_w;
3900wire flip_size_b;
3901
3902wire atomic_b;
3903wire rmo_st_b;
3904wire blk_inst_b;
3905reg blk_inst_w;
3906
3907wire bst_in_prog_b;
3908reg bst_in_prog_w;
3909wire [39:0] bst_pa_b;
3910reg [39:0] bst_pa_w;
3911wire [2:0] bst_tid_b;
3912reg [2:0] bst_tid_w;
3913wire [39:0] st_pa_b;
3914reg [39:0] st_pa_w;
3915wire [2:0] st_tid_b;
3916reg [2:0] st_tid_w;
3917
3918wire store_inv_e;
3919reg store_inv_m;
3920reg store_inv_b;
3921reg store_inv_w;
3922wire [5:0] stinv_tnum_e;
3923reg [5:0] stinv_tnum_m;
3924reg [5:0] stinv_tnum_b;
3925reg [5:0] stinv_tnum_w;
3926
3927wire store_update_e;
3928reg store_update_m;
3929reg store_update_b;
3930reg store_update_w;
3931wire [2:0] stu_tid_e;
3932reg [2:0] stu_tid_m;
3933reg [2:0] stu_tid_b;
3934reg [2:0] stu_tid_w;
3935wire [5:0] stu_tnum_e;
3936reg [5:0] stu_tnum_m;
3937reg [5:0] stu_tnum_b;
3938reg [5:0] stu_tnum_w;
3939
3940wire [7:0] asi_st_dequeue;
3941wire [7:0] st_ack_no_asi_e;
3942reg [7:0] st_ack_no_asi_m;
3943reg [7:0] st_ack_no_asi_b;
3944wire [7:0] store_ack_b;
3945reg [7:0] store_ack_w;
3946wire [7:0] st_ack_rmo_b;
3947reg [7:0] st_ack_rmo_w;
3948reg sta_rmo;
3949reg [2:0] sta_tid;
3950reg [5:0] sta_tnum;
3951reg sta_suppress [0:7]; // 1 per thread
3952wire st_io_asi;
3953wire [2:0] st_io_tid;
3954wire [7:0] st_data_access_e;
3955reg [7:0] st_data_access_m;
3956reg [7:0] st_data_access_b;
3957reg [7:0] st_data_access_w;
3958reg [2:0] tmp_tid;
3959reg [5:0] tmp_tnum;
3960
3961reg [39:0] store_pa_m;
3962reg [39:0] store_pa_b;
3963reg [39:0] store_pa_w;
3964
3965wire [1:0] l1_way_select;
3966wire [6:0] l1_index;
3967wire [27:0] my_way;
3968wire [27:0] way0;
3969wire [27:0] way1;
3970wire [27:0] way2;
3971wire [27:0] way3;
3972
3973wire [3:0] evict_inv_e;
3974reg [3:0] evict_inv_m;
3975reg [3:0] evict_inv_b;
3976reg [3:0] evict_inv_w;
3977wire [2:0] evict_srcid_e;
3978reg [2:0] evict_srcid_m;
3979reg [2:0] evict_srcid_b;
3980reg [2:0] evict_srcid_w;
3981
3982wire [8:0] pcx_req;
3983reg [8:0] pcx_req_1;
3984wire [129:0] pcx_data;
3985
3986wire perfmon;
3987wire perfmon_g;
3988reg perfmon_m;
3989reg perfmon_b;
3990reg perfmon_w;
3991wire [2:0] perfmon_tid;
3992wire [2:0] perfmon_tid_g;
3993reg [2:0] perfmon_tid_m;
3994reg [2:0] perfmon_tid_b;
3995reg [2:0] perfmon_tid_w;
3996wire [5:0] perfmon_tnum;
3997wire [7:0] perfmon_mask;
3998wire [7:0] perfmon_mask_g;
3999reg [7:0] perfmon_mask_m;
4000reg [7:0] perfmon_mask_b;
4001reg [7:0] perfmon_mask_w;
4002
4003wire [7:0] bst_kill;
4004reg [2:0] bst_kill_tid;
4005reg [5:0] bst_kill_tnum;
4006
4007wire [7:0] stb_state0_m;
4008wire [7:0] stb_state1_m;
4009wire [7:0] stb_state2_m;
4010wire [7:0] stb_state3_m;
4011wire [7:0] stb_state4_m;
4012wire [7:0] stb_state5_m;
4013wire [7:0] stb_state6_m;
4014wire [7:0] stb_state7_m;
4015reg [7:0] stb_state0_b;
4016reg [7:0] stb_state1_b;
4017reg [7:0] stb_state2_b;
4018reg [7:0] stb_state3_b;
4019reg [7:0] stb_state4_b;
4020reg [7:0] stb_state5_b;
4021reg [7:0] stb_state6_b;
4022reg [7:0] stb_state7_b;
4023reg [7:0] stb_state0_w;
4024reg [7:0] stb_state1_w;
4025reg [7:0] stb_state2_w;
4026reg [7:0] stb_state3_w;
4027reg [7:0] stb_state4_w;
4028reg [7:0] stb_state5_w;
4029reg [7:0] stb_state6_w;
4030reg [7:0] stb_state7_w;
4031reg [7:0] stb_state;
4032reg stb_last;
4033
4034// Copy of dtag
4035reg [27:0] dta_way0 [127:0];
4036reg [27:0] dta_way1 [127:0];
4037reg [27:0] dta_way2 [127:0];
4038reg [27:0] dta_way3 [127:0];
4039
4040//---------------------
4041// Misc Signals
4042wire [2:0] mycid;
4043integer tstamp;
4044integer junk;
4045integer i;
4046
4047initial begin // {
4048 ldf_tnum_w = 6'b0;
4049 dsrc = 2'b0;
4050 sta_tid = 3'b0;
4051 sta_tnum = 6'b0;
4052 for (i=0; i<=7; i=i+1) begin
4053 sta_suppress[i] = 1'b0;
4054 end
4055
4056end // }
4057
4058// for debug only - allows display in Debussy
4059wire sta_suppress0;
4060wire sta_suppress1;
4061wire sta_suppress2;
4062wire sta_suppress3;
4063wire sta_suppress4;
4064wire sta_suppress5;
4065wire sta_suppress6;
4066wire sta_suppress7;
4067
4068 assign sta_suppress0 = sta_suppress[0];
4069 assign sta_suppress1 = sta_suppress[1];
4070 assign sta_suppress2 = sta_suppress[2];
4071 assign sta_suppress3 = sta_suppress[3];
4072 assign sta_suppress4 = sta_suppress[4];
4073 assign sta_suppress5 = sta_suppress[5];
4074 assign sta_suppress6 = sta_suppress[6];
4075 assign sta_suppress7 = sta_suppress[7];
4076
4077//----------------------------------------------------------
4078//----------------------------------------------------------
4079// DUT probes
4080
4081 assign mycid = 4;
4082
4083//---------------------
4084// Load Issue
4085
4086 // If Load to IO ASIs, load issue should not be sent.
4087 // In this case, asi_internal_w is asserted and will suppress load_w.
4088
4089 assign load_w = `SPC4.lsu.dcc.ld_inst_vld_w &
4090 ~`PROBES4.asi_internal_w &
4091 ~`SPC4.lsu.dcc.flush_w &
4092 ~ldi_pf_w;
4093
4094 // ldxa to IO ASI are already suppressed since load_w will not assert.
4095 // ldi_suppress is required to also suppress normal ld to IO ASI address range.
4096 assign ldi_suppress = (ldi_pa_w[39:32] == `IO_ASI_ADDR);
4097
4098 assign ldi_tid_w = `SPC4.lsu.dcc.tid_w;
4099 assign ldi_tnum_w = {mycid,ldi_tid_w};
4100 assign ldi_size_b = `SPC4.lsu.dcc.ldst_sz_b; // 2 bits
4101 assign ldi_atomic_b = `SPC4.lsu.dcc.atomic_b;
4102 assign ldi_qld_b = `SPC4.lsu.dcc.quad_ldd_b;
4103 assign ldi_ldbl_b = `SPC4.lsu.dcc_ldbl_b;
4104 assign ldi_ldd_b = ldi_ldbl_b & !ldi_qld_b;
4105 assign ldi_bld_b = `SPC4.lsu.dcc.dcc_blk_inst_b;
4106 assign ldi_pf_b = `SPC4.lsu.dcc.pref_inst_b;
4107
4108 // pa, tid are same for LoadIssue and StoreIssue
4109 assign ldi_pa_b = {`SPC4.lsu.tlb_pgnum[39:13],
4110 `SPC4.lsu.lmd.lsu_va_b[12:0]};
4111
4112//---------------------
4113// Load Fill
4114
4115 assign load_fill_e = `SPC4.lsu.dcc.ld_fill_e;
4116 assign ldf_tid_e = `SPC4.lsu.cid.cid_tid;
4117 assign ldf_pa_e = {`SPC4.lsu.lmd.lmd_fill_addr_e[39:3],3'b0};
4118
4119//---------------------
4120// Store Issue
4121
4122 // blk_inst_w will suppress store_w for 1st of 9 cycles on block store.
4123
4124 // If Store to IO ASIs, store issue should not be sent.
4125 // In this case, asi_internal_w is asserted and will suppress store_w.
4126
4127 assign unflushed_store_w = `SPC4.lsu.sbc.unflushed_store_w;
4128
4129 assign store_w = unflushed_store_w &
4130 (~(`PROBES4.asi_internal_w | blk_inst_w) |
4131 bst_in_prog_w);
4132
4133 assign atomic_b = `SPC4.lsu.dcc.atomic_b;
4134 assign rmo_st_b = `SPC4.lsu.sbc_rmo_st_b;
4135 assign blk_inst_b = `SPC4.lsu.dcc.dcc_blk_inst_b;
4136
4137 assign sti_tnum_w = {mycid,sti_tid_w};
4138 assign sti_size_m = `SPC4.lsu.dcc_ldst_bmask;
4139
4140 // flip_size will assert if endian swap for partial store is needed
4141 assign flip_size_b = `SPC4.lsu.dcc.pst_asi_b & `SPC4.lsu.dcc.tlb_tte_ie_b & `SPC4.lsu.dcc.tlb_tte_vld_b & `SPC4.lsu.dcc.st_inst_vld_b;
4142
4143 // Change itype only when control signals are valid
4144 assign sti_itype_w = unflushed_store_w ? itype_w : sti_itype_w;
4145
4146 // It is correct to mix W & B stage signals for this.
4147 // STD is a 2 cycle instruction.
4148 // inst valid in W, data in B (1 cycle behind)
4149 assign sti_data_w = `SPC4.lsu.sbc.std_inst_w ?
4150 sbd_st_data_b :
4151 sbd_st_data_w;
4152 assign sbd_st_data_b = `SPC4.lsu.sbd_st_data_b;
4153
4154 // Use different pa,tid if block store
4155 assign sti_pa_b = bst_in_prog_b ? bst_pa_b : st_pa_b;
4156 assign sti_tid_b = bst_in_prog_b ? bst_tid_b : st_tid_b;
4157
4158 // stxa to IO ASI are already suppressed since store_w will not assert.
4159 // sti_suppress is required to also suppress normal st to IO ASI address range.
4160 assign sti_suppress = (sti_pa_w[39:32] == `IO_ASI_ADDR);
4161
4162 // Normal Store
4163 assign st_pa_b = {`SPC4.lsu.tlb_pgnum[39:13],
4164 `SPC4.lsu.lmd.lsu_va_b[12:0]};
4165 assign st_tid_b = `SPC4.lsu.dcc.tid_b;
4166
4167 // Block Store
4168 assign bst_in_prog_b = `SPC4.lsu.sbc.bst_in_prog_b;
4169 assign bst_pa_b = {`SPC4.lsu.sbd.st_addr_b[39:3],3'b0};
4170 assign bst_tid_b = `SPC4.lsu.sbc.bst_tid;
4171
4172//---------------------
4173// Store Ack
4174
4175assign asi_st_dequeue[7:0] = `SPC4.lsu.dcc_asi_rtn_vld[7:0] &
4176 {8{~`SPC4.lsu.dcc_asi_rtn_rd}};
4177
4178 assign st_ack_no_asi_e = `SPC4.lsu.cic.cic_st_dequeue[7:0] &
4179 ~asi_st_dequeue[7:0] &
4180 ~`SPC4.lsu.cic.sbc_bst_sel[7:0];
4181
4182 assign st_ack_rmo_b = {`SPC4.lsu.sbs7.rmo_st_commit_p4,
4183 `SPC4.lsu.sbs6.rmo_st_commit_p4,
4184 `SPC4.lsu.sbs5.rmo_st_commit_p4,
4185 `SPC4.lsu.sbs4.rmo_st_commit_p4,
4186 `SPC4.lsu.sbs3.rmo_st_commit_p4,
4187 `SPC4.lsu.sbs2.rmo_st_commit_p4,
4188 `SPC4.lsu.sbs1.rmo_st_commit_p4,
4189 `SPC4.lsu.sbs0.rmo_st_commit_p4
4190 };
4191
4192 // It is possible to see 2 threads store_ack in same cycle
4193 // (1 st_ack_no_asi & 1 st_ack_rmo)
4194
4195 assign store_ack_b = st_ack_no_asi_b | st_ack_rmo_b;
4196
4197 // cic_st_atm_cmplt is atomic store completing (same time as store ack)
4198 // (lsu.lmc.dcl2u_err | dcl2nd_err) indicate a data_access_error condition
4199 assign st_data_access_e = {8{(`SPC4.lsu.cic.cic_st_atm_cmplt &
4200 (`SPC4.lsu.lmc.dcl2u_err | `SPC4.lsu.lmc.dcl2nd_err))}} &
4201 `SPC4.lsu.cic.cic_st_dequeue[7:0];
4202//---------------------
4203// Store Inv
4204
4205 // Same as evict_inv_e but with cpq_evict deasserted
4206 assign store_inv_e = `SPC4.lsu.cic_invalidate_e &
4207 (`SPC4.lsu.cic_inv_wen_e!=0)&
4208 ~`SPC4.lsu.cic.cpq_evict &
4209 ~`SPC4.lsu.cic.cid_set_inval &
4210 ~`SPC4.lsu.cic.cic_xinval_e &
4211 ~(`SPC4.lsu.cic.cid_pkt_type[4:0] == 5'b10110);
4212 assign stinv_tnum_e =
4213 {`SPC4.lsu.cid.cpq_data_out[`CPX_VACK_CID],
4214 `SPC4.lsu.cid.cid_tid};
4215
4216//---------------------
4217// Store Update
4218
4219 assign store_update_e = `SPC4.lsu.cic_st_update_e;
4220 assign stu_tid_e = `SPC4.lsu.cid.cid_tid;
4221 assign stu_tnum_e = {mycid,stu_tid_e};
4222
4223 assign l1_index = {`SPC4.lsu.cid.cpq_data_out[116],
4224 `SPC4.lsu.cid.cpq_data_out[115],
4225 `SPC4.lsu.cid.cpq_data_out[114],
4226 `SPC4.lsu.cid.cpq_data_out[113],
4227 `SPC4.lsu.cid.cpq_data_out[112],
4228 `SPC4.lsu.cid.cpq_data_out[122],
4229 `SPC4.lsu.cid.cpq_data_out[121]
4230 };
4231 assign l1_way_select = `SPC4.lsu.cid_inv_vec[17:16];
4232
4233//---------------------
4234// EvictInv
4235
4236 // Same as store_inv_e but with cpq_evict asserted
4237 // LSU can invalidate 1-4 Dcache lines
4238 assign evict_inv_e[3:0] = {4{`SPC4.lsu.cic_invalidate_e & // enable for 4 bit wen below
4239 (`SPC4.lsu.cic_inv_wen_e!=0)&
4240 `SPC4.lsu.cic.cpq_evict &
4241 ~`SPC4.lsu.cic.cid_set_inval &
4242 ~`SPC4.lsu.cic.cic_xinval_e}} &
4243
4244 {|(`SPC4.lsu.cic.evict_inv_wen[15:12]), // 4 bit field - 1 hot. Send evinv when any one set.
4245 |(`SPC4.lsu.cic.evict_inv_wen[11:8]),
4246 |(`SPC4.lsu.cic.evict_inv_wen[7:4]),
4247 |(`SPC4.lsu.cic.evict_inv_wen[3:0])
4248 };
4249
4250 assign evict_srcid_e = `SPC4.lsu.cid.cpq_data_out[114:112];
4251
4252
4253//---------------------
4254// Detect Store to IO ASI in PCX crossbar packet.
4255// This causes next Store Ack to be suppressed.
4256
4257// Normal Store only since atomics are always to cacheable space
4258
4259// Trigger on Store to crossbar.
4260// If Store request is retried on crossbar (due to no grant),
4261// then, st_io_asi will fire multiple times for the same request.
4262// This is OK because it just causes sta_suppress to be set multiple times.
4263
4264 assign pcx_req = `SPC4.spc_pcx_req_pq;
4265 assign pcx_data = `SPC4.spc_pcx_data_pa;
4266
4267 assign st_io_asi = (pcx_req_1 != 9'b0) &
4268 (pcx_data [`PCX_VALID]==1'b1) &
4269 (pcx_data [`PCX_RQTYP]==`CCX_REQ_ST) &
4270 (pcx_data [103:96]==`IO_ASI_ADDR); // Upper byte of 40 bit addr
4271
4272 assign st_io_tid = pcx_data [`PCX_TID];
4273
4274 assign stb_state0_m = `SPC4.lsu.sbs0.stb_state_vld[7:0];
4275 assign stb_state1_m = `SPC4.lsu.sbs1.stb_state_vld[7:0];
4276 assign stb_state2_m = `SPC4.lsu.sbs2.stb_state_vld[7:0];
4277 assign stb_state3_m = `SPC4.lsu.sbs3.stb_state_vld[7:0];
4278 assign stb_state4_m = `SPC4.lsu.sbs4.stb_state_vld[7:0];
4279 assign stb_state5_m = `SPC4.lsu.sbs5.stb_state_vld[7:0];
4280 assign stb_state6_m = `SPC4.lsu.sbs6.stb_state_vld[7:0];
4281 assign stb_state7_m = `SPC4.lsu.sbs7.stb_state_vld[7:0];
4282
4283//---------------------
4284// Load Data (hit only) (See ldst_l2.v for Load Data - miss)
4285
4286 assign load_data_hit = load_w && (hit_w | fraw_w);
4287 assign ld_miss_b = `SPC4.lsu.dcc.dcc_ld_miss_b;
4288 assign fraw_w = `SPC4.lsu.lmc.ld_raw_bypass_w;
4289 assign hit_w = ~ld_miss_w & ~stb_hit_w;
4290 assign miss_w = ~fraw_w & (ld_miss_w | stb_hit_w);
4291
4292//---------------------
4293// Load Pop
4294
4295 assign perfmon_g = `SPC4.lsu.lsu_perfmon_trap_g;
4296 assign perfmon_tid_g = `SPC4.lsu.lsu_dcerr_tid_g;
4297 // perfmon_mask will not fire if trap is not enabled or higher priority trap is taken.
4298 assign perfmon_mask_g = {`SPC4.tlu.fls1.pil_mask_15[3:0], `SPC4.tlu.fls0.pil_mask_15[3:0]} &
4299 ~{8 {`SPC4.lsu_dcl2u_err_g | `SPC4.lsu_dcl2nd_err_g}};
4300
4301 assign perfmon = perfmon_w;
4302 assign perfmon_tid = perfmon_tid_w;
4303 assign perfmon_tnum = {mycid,perfmon_tid_w};
4304 assign perfmon_mask = perfmon_mask_w;
4305
4306
4307
4308//---------------------
4309// Store Pop
4310
4311 assign bst_kill = {`SPC4.lsu.sbs7.bst_kill,
4312 `SPC4.lsu.sbs6.bst_kill,
4313 `SPC4.lsu.sbs5.bst_kill,
4314 `SPC4.lsu.sbs4.bst_kill,
4315 `SPC4.lsu.sbs3.bst_kill,
4316 `SPC4.lsu.sbs2.bst_kill,
4317 `SPC4.lsu.sbs1.bst_kill,
4318 `SPC4.lsu.sbs0.bst_kill};
4319
4320//----------------------------------------------------------
4321//----------------------------------------------------------
4322
4323always @ (posedge `SPC4.l2clk) begin // {
4324
4325 tstamp = `TOP.core_cycle_cnt - 1;
4326
4327 //------------------------------
4328 // Pipeline from B to W
4329
4330 ldi_pa_w <= ldi_pa_b;
4331 ld_miss_w <= ld_miss_b;
4332 stb_hit_w <= `SPC4.lsu.stb_cam_hit;
4333 ldi_pf_w <= ldi_pf_b;
4334 ldi_size_w <= ldi_size_b;
4335 load_fill_m <= load_fill_e;
4336 load_fill_b <= load_fill_m;
4337 load_fill_w <= load_fill_b;
4338 ldf_tid_m <= ldf_tid_e;
4339 ldf_tid_b <= ldf_tid_m;
4340 ldf_tid_w <= ldf_tid_b;
4341 ldf_pa_m <= ldf_pa_e;
4342 ldf_pa_b <= ldf_pa_m;
4343 ldf_pa_w <= ldf_pa_b;
4344
4345 sti_size_b <= sti_size_m;
4346 sti_size_w <= (flip_size_b) ? {sti_size_b[0],sti_size_b[1],sti_size_b[2],sti_size_b[3],
4347 sti_size_b[4],sti_size_b[5],sti_size_b[6],sti_size_b[7]}
4348 : sti_size_b;
4349 sti_pa_w <= sti_pa_b;
4350 sti_tid_w <= sti_tid_b;
4351 st_ack_no_asi_m <= st_ack_no_asi_e;
4352 st_ack_no_asi_b <= st_ack_no_asi_m;
4353 st_data_access_m <= st_data_access_e;
4354 st_data_access_b <= st_data_access_m;
4355 st_data_access_w <= st_data_access_b;
4356 store_ack_w <= store_ack_b;
4357 store_update_m <= store_update_e;
4358 store_update_b <= store_update_m;
4359 store_update_w <= store_update_b;
4360 store_inv_m <= store_inv_e;
4361 store_inv_b <= store_inv_m;
4362 store_inv_w <= store_inv_b;
4363 stinv_tnum_m <= stinv_tnum_e;
4364 stinv_tnum_b <= stinv_tnum_m;
4365 stinv_tnum_w <= stinv_tnum_b;
4366 st_ack_rmo_w <= st_ack_rmo_b;
4367 stu_tid_m <= stu_tid_e;
4368 stu_tid_b <= stu_tid_m;
4369 stu_tid_w <= stu_tid_b;
4370 stu_tnum_m <= stu_tnum_e;
4371 stu_tnum_b <= stu_tnum_m;
4372 stu_tnum_w <= stu_tnum_b;
4373 store_pa_b <= store_pa_m;
4374 store_pa_w <= store_pa_b;
4375 bst_in_prog_w <= bst_in_prog_b;
4376 blk_inst_w <= blk_inst_b;
4377 sbd_st_data_w <= sbd_st_data_b;
4378 evict_inv_m <= evict_inv_e;
4379 evict_inv_b <= evict_inv_m;
4380 evict_inv_w <= evict_inv_b;
4381 evict_srcid_m <= evict_srcid_e;
4382 evict_srcid_b <= evict_srcid_m;
4383 evict_srcid_w <= evict_srcid_b;
4384 pcx_req_1 <= pcx_req;
4385 stb_state0_b <= stb_state0_m;
4386 stb_state1_b <= stb_state1_m;
4387 stb_state2_b <= stb_state2_m;
4388 stb_state3_b <= stb_state3_m;
4389 stb_state4_b <= stb_state4_m;
4390 stb_state5_b <= stb_state5_m;
4391 stb_state6_b <= stb_state6_m;
4392 stb_state7_b <= stb_state7_m;
4393 stb_state0_w <= stb_state0_b;
4394 stb_state1_w <= stb_state1_b;
4395 stb_state2_w <= stb_state2_b;
4396 stb_state3_w <= stb_state3_b;
4397 stb_state4_w <= stb_state4_b;
4398 stb_state5_w <= stb_state5_b;
4399 stb_state6_w <= stb_state6_b;
4400 stb_state7_w <= stb_state7_b;
4401
4402 perfmon_m <= perfmon_g;
4403 perfmon_b <= perfmon_m;
4404 perfmon_w <= perfmon_b;
4405 perfmon_tid_m <= perfmon_tid_g;
4406 perfmon_tid_b <= perfmon_tid_m;
4407 perfmon_tid_w <= perfmon_tid_b;
4408 perfmon_mask_m <= perfmon_mask_g;
4409 perfmon_mask_b <= perfmon_mask_m;
4410 perfmon_mask_w <= perfmon_mask_b;
4411
4412 //----------------------------------------------------------
4413 // Calculate pa for STUPDATE and STINV
4414 // Moved this into the always block to avoid the constant
4415 // probing of the dtag memory structure.
4416
4417 if (store_inv_e | store_update_e) begin // {
4418 store_pa_m[2:0] <= 3'b000;
4419 store_pa_m[10:3] <= {`SPC4.lsu.cid.cpq_data_out[116],
4420 `SPC4.lsu.cid.cpq_data_out[115],
4421 `SPC4.lsu.cid.cpq_data_out[114],
4422 `SPC4.lsu.cid.cpq_data_out[113],
4423 `SPC4.lsu.cid.cpq_data_out[112],
4424 `SPC4.lsu.cid.cpq_data_out[122],
4425 `SPC4.lsu.cid.cpq_data_out[121],
4426 `SPC4.lsu.cid.cpq_data_out[104]
4427 };
4428 store_pa_m[38:11] <= (l1_way_select==2'h0) ? dta_way0[l1_index] :
4429 (l1_way_select==2'h1) ? dta_way1[l1_index] :
4430 (l1_way_select==2'h2) ? dta_way2[l1_index] : dta_way3[l1_index];
4431 store_pa_m[39] <= 1'b0; // Only memory stores get inv/update
4432 end // }
4433
4434
4435 // After Store to IO ASI is detected at StI time, suppress the next Store Ack
4436 // There is only 1 store to IO ASI active at one time per thread because
4437 // that is all the LSU allows.
4438 if (st_io_asi) begin
4439 sta_suppress [st_io_tid] <= 1'b1;
4440 end
4441
4442 case ({ldi_atomic_b,ldi_bld_b,ldi_ldd_b,ldi_qld_b,ldi_pf_b})
4443 5'b00000: ldi_itype_w <= `ITYPE_LOAD;
4444 5'b00001: ldi_itype_w <= `ITYPE_PREFETCH;
4445 5'b00010: ldi_itype_w <= `ITYPE_QUAD_LOAD;
4446 5'b00100: ldi_itype_w <= `ITYPE_DOUBLE_LOAD;
4447 5'b01000: ldi_itype_w <= `ITYPE_BLOCK_LOAD;
4448 5'b10000: ldi_itype_w <= `ITYPE_ATOMIC;
4449 default: ldi_itype_w <= `ITYPE_NO; // Illegal
4450 endcase
4451
4452 case ({atomic_b,rmo_st_b,bst_in_prog_b})
4453 3'b000: itype_w <= `ITYPE_STORE;
4454 3'b010: itype_w <= `ITYPE_BLK_INIT_ST;
4455 3'b011: itype_w <= `ITYPE_BLOCK_STORE;
4456 3'b100: itype_w <= `ITYPE_ATOMIC;
4457 3'b001,
4458 3'b101,
4459 3'b110,
4460 3'b111: itype_w <= `ITYPE_NO; // Illegal
4461 endcase
4462
4463 //----------------------------------------------------------
4464 //----------------------------------------------------------
4465 // Load Issue
4466
4467 // Load Issue must be before Store Issue for atomic
4468
4469 if (load_w) begin // {
4470
4471 if (ldi_suppress==1'b0) begin // {
4472 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
4473 `PR_INFO ("pli_ldst", `INFO,
4474 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h size=%h typ=%0h ts=%0d",
4475 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
4476 junk = $sim_send(`PLI_MEM_LD_ISSUE,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
4477 end // }
4478 end // }
4479 else begin // {
4480 `PR_INFO ("pli_ldst", `INFO,
4481 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h Suppress for IO ASI",mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w);
4482 end // }
4483
4484 if (`PARGS.show_memop_on) begin // {
4485 `PR_NORMAL ("pli_ldst", `NORMAL,
4486 "C%0d T%0d MEMOP_LOAD tid=%d pa=%h ts=%0d (LSU - W stage)",
4487 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,tstamp);
4488 end // }
4489
4490 end // }
4491
4492 //----------------------------------------------------------
4493 //----------------------------------------------------------
4494 // Load Data (hit only) (See ldst_l2.v for Load Data - miss)
4495
4496 if (load_data_hit) begin // {
4497
4498 dsrc = hit_w ? `DSRC_L1 : `DSRC_STB;
4499
4500 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
4501 `PR_INFO ("pli_ldst", `INFO,
4502 "C%0d T%0d PLI_MEM_LDDATA tid=%d pa=%h dsrc=%0h ts=%0d",
4503 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
4504 junk = $sim_send(`PLI_MEM_LD_DATA,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
4505 end // }
4506
4507 end // }
4508
4509
4510 //----------------------------------------------------------
4511 //----------------------------------------------------------
4512 // Store Ack
4513 //
4514 // Store Ack cmd must be sent before Store Inv, Store Update for NAS
4515 // Store Ack & Store Update will be in the same timestamp
4516
4517 if (store_ack_w != 8'b0) begin // {
4518
4519 for (i=0; i<=7; i=i+1) begin // {
4520 if (store_ack_w[i]) begin // {
4521 sta_tid = i[2:0];
4522 sta_tnum = {mycid,sta_tid};
4523 sta_rmo = st_ack_rmo_w[i];
4524
4525 if (sta_suppress[sta_tid]==1'b0) begin // {
4526 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
4527 `PR_INFO ("pli_ldst", `INFO,
4528 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
4529 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
4530 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
4531 end // }
4532 end // }
4533
4534 else begin // {
4535
4536 // It is possible for 2 Stores it be in flight because of the delay from CPQ push & pop.
4537 // So, make sure Bench is suppressing the correct Store.
4538 case (sta_tid)
4539 3'h0: stb_state=stb_state0_w;
4540 3'h1: stb_state=stb_state1_w;
4541 3'h2: stb_state=stb_state2_w;
4542 3'h3: stb_state=stb_state3_w;
4543 3'h4: stb_state=stb_state4_w;
4544 3'h5: stb_state=stb_state5_w;
4545 3'h6: stb_state=stb_state6_w;
4546 3'h7: stb_state=stb_state7_w;
4547 default:
4548 `PR_ERROR ("pli_ldst", `ERROR,
4549 "C%0d T%0d PLI_MEM_XXX Bench Error. Should never execute case default",mycid,sta_tid);
4550 endcase
4551
4552 // If stb_state has only 1 bit asserted, then suppress the STACK. Otherwise, send the STACK.
4553 case (stb_state) // {
4554 8'b0000_0000: begin
4555 `PR_ERROR ("pli_ldst", `ERROR,
4556 "C%0d T%0d PLI_MEM_XXX Bench Error. stb_state should not be 8'b0",
4557 mycid,sta_tid);
4558 end
4559 8'b0000_0001,
4560 8'b0000_0010,
4561 8'b0000_0100,
4562 8'b0000_1000,
4563 8'b0001_0000,
4564 8'b0010_0000,
4565 8'b0100_0000,
4566 8'b1000_0000: stb_last = 1'b1;
4567 default: stb_last = 1'b0;
4568 endcase // }
4569
4570 if (stb_last==1'b0) begin // {
4571 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
4572 `PR_INFO ("pli_ldst", `INFO,
4573 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
4574 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
4575 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
4576 end // }
4577 end // }
4578 else begin // {
4579 sta_suppress[sta_tid] <= 1'b0;
4580 `PR_INFO ("pli_ldst", `INFO,
4581 "C%0d T%0d PLI_MEM_STACK tid=%d Suppress for IO ASI",mycid,sta_tid,sta_tnum);
4582 end // }
4583 end // }
4584
4585 end // if (store_ack_w[i]) }
4586 end // for }
4587
4588 end // if (store_ack_w) }
4589
4590 //----------------------------------------------------------
4591 //----------------------------------------------------------
4592 // Store Inv
4593
4594 if (store_inv_w) begin // {
4595
4596 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stinv_tnum_w]) begin // {
4597 `PR_INFO ("pli_ldst", `INFO,
4598 "C%0d PLI_MEM_STINV tid=%d pa=%h cid=%h ts=%0d",
4599 mycid,stinv_tnum_w,store_pa_w,mycid,tstamp);
4600 junk = $sim_send(`PLI_MEM_ST_INV,mycid,stinv_tnum_w,store_pa_w,tstamp);
4601 end // }
4602
4603 end // }
4604
4605
4606 //----------------------------------------------------------
4607 //----------------------------------------------------------
4608 // Store Update
4609
4610 if (store_update_w) begin // {
4611
4612 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stu_tnum_w]) begin // {
4613 `PR_INFO ("pli_ldst", `INFO,
4614 "C%0d T%0d PLI_MEM_STUP tid=%d pa=%h ts=%0d",
4615 mycid,stu_tid_w,stu_tnum_w,store_pa_w,tstamp);
4616 junk = $sim_send(`PLI_MEM_ST_UPDATE,stu_tnum_w,store_pa_w,tstamp);
4617 end // }
4618
4619 end // }
4620
4621 //----------------------------------------------------------
4622 //----------------------------------------------------------
4623 // Load Fill
4624
4625 if (load_fill_w) begin // {
4626
4627 ldf_tnum_w = {mycid,ldf_tid_w};
4628
4629 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldf_tnum_w]) begin // {
4630 `PR_INFO ("pli_ldst", `INFO,
4631 "C%0d T%0d PLI_MEM_LDFILL tid=%d pa=%h ts=%0d",
4632 mycid,ldf_tid_w,ldf_tnum_w,ldf_pa_w,tstamp);
4633 junk = $sim_send(`PLI_MEM_LD_FILL,ldf_tnum_w,ldf_pa_w,tstamp);
4634 end // }
4635
4636 end // }
4637
4638 //----------------------------------------------------------
4639 //----------------------------------------------------------
4640 // Store Issue
4641
4642 if (store_w) begin // {
4643
4644 if (sti_suppress==1'b0) begin // {
4645 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sti_tnum_w]) begin // {
4646 `PR_INFO ("pli_ldst", `INFO,
4647 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h data=%h sz=%h typ=%0h ts=%0d",
4648 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
4649 junk = $sim_send(`PLI_MEM_ST_ISSUE,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
4650 end // }
4651
4652 end // }
4653 else begin // {
4654 `PR_INFO ("pli_ldst", `INFO,
4655 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h Suppress for IO ASI",mycid,sti_tid_w,sti_tnum_w,sti_pa_w);
4656 end // }
4657
4658 if (`PARGS.show_memop_on) begin // {
4659 `PR_NORMAL ("pli_ldst", `NORMAL,
4660 "C%0d T%0d MEMOP_STORE tid=%d pa=%h data=%h sz=%h ts=%0d (LSU - W stage)",
4661 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,tstamp);
4662 end // }
4663
4664 end // }
4665
4666 //----------------------------------------------------------
4667 //----------------------------------------------------------
4668 // EvictInv
4669 // Send 1-4 EvictInv messages per cycle - based on how many Dcache lines were invalidated.
4670
4671 for (i=0; i<=3; i=i+1) begin // {
4672 if (evict_inv_w[i]) begin // {
4673
4674 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on) begin // {
4675 `PR_INFO ("pli_ldst", `INFO,
4676 "C%0d PLI_MEM_EVINV cid=%d srcid=%0d ts=%0d",
4677 mycid,mycid,evict_srcid_w,tstamp);
4678 junk = $sim_send(`PLI_MEM_EVICT_INV,mycid,evict_srcid_w,tstamp);
4679 end // }
4680
4681 end // }
4682 end // }
4683
4684 //----------------------------------------------------------
4685 //----------------------------------------------------------
4686 // Load Pop - special case
4687
4688 // This is required in case of a performance monitor trap due to L2 miss.
4689 // In this case, the trap is not indicated until after the Load pkt returns to the LSU.
4690 // ldst_sync has already sent LDISSUE and LDDATA to Riesling. But, the Load is not executed.
4691 // Load Pop tells Riesling to pop the LDISSUE,LDDATA off of its queues.
4692
4693 if (perfmon & perfmon_mask[perfmon_tid]) begin // {
4694
4695 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[perfmon_tnum]) begin // {
4696 `PR_INFO ("pli_ldst", `INFO,
4697 "C%0d T%0d PLI_MEM_LDPOP tid=%d ts=%0d",
4698 mycid,perfmon_tid,perfmon_tnum,tstamp);
4699 junk = $sim_send(`PLI_MEM_LD_POP,perfmon_tnum);
4700 end // }
4701
4702 end // }
4703
4704 //----------------------------------------------------------
4705 //----------------------------------------------------------
4706 // Store Pop - special cases
4707
4708 // This is required in case of a FRF error trap (internal_proc_error) on a Block Store.
4709 // In this case, the trap is not indicated until after the 8 STISSUE has been sent to Riesling.
4710 // But, the Store is not executed.
4711 // Store Pop tells Riesling to pop the 8 STISSUE off of its queues.
4712
4713 if (bst_kill!==8'b0) begin // {
4714
4715 for (i=0;i<=7;i=i+1) begin
4716 if (bst_kill[i]==1'b1) begin
4717 bst_kill_tid = i;
4718 bst_kill_tnum = {mycid,bst_kill_tid};
4719
4720 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[bst_kill_tnum]) begin // {
4721 `PR_INFO ("pli_ldst", `INFO,
4722 "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
4723 mycid,bst_kill_tid,bst_kill_tnum,tstamp);
4724 junk = $sim_send(`PLI_MEM_ST_POP,bst_kill_tnum);
4725 end // }
4726 end
4727 end
4728
4729 end // }
4730
4731 //--------------------
4732 // This is required for data_access_error on atomic. In this case, Riesling only cleans up the Load,
4733 // but doesn't know it is an atomic so Riesling doesn't clean up the store in its buffers.
4734 // The STPOP tells Riesling to clear the newest Store from the buffers.
4735 // It is possible to have older Stores in-flight but not newer Stores in-flight.
4736
4737// if (st_data_access_w != 8'b0) begin // {
4738//
4739// for (i=0; i<=7; i=i+1) begin // {
4740// if (st_data_access_w[i]) begin // {
4741// tmp_tid = i[2:0];
4742// tmp_tnum = {mycid,tmp_tid};
4743//
4744// if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[tmp_tnum]) begin // {
4745// `PR_INFO ("pli_ldst", `INFO,
4746// "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
4747// mycid,tmp_tid,tmp_tnum,tstamp);
4748// junk = $sim_send(`PLI_MEM_ST_POP,tmp_tnum);
4749// end // }
4750// end // } if st_data_access[i]
4751// end // } for
4752// end // } if st_data_access
4753
4754end // always }
4755
4756//----------------------------------------------------------
4757// Need to model the D arrays to get PA's for store updates and invalidates
4758
4759always @ (negedge `SPC4.l2clk) begin // {
4760 if (`SPC4.lsu.dta.wr_way[0])
4761 dta_way0[`SPC4.lsu.dta.index_y[6:0]] <= `SPC4.lsu.dta.wrtag_y[27:0];
4762 if (`SPC4.lsu.dta.wr_way[1])
4763 dta_way1[`SPC4.lsu.dta.index_y[6:0]] <= `SPC4.lsu.dta.wrtag_y[27:0];
4764 if (`SPC4.lsu.dta.wr_way[2])
4765 dta_way2[`SPC4.lsu.dta.index_y[6:0]] <= `SPC4.lsu.dta.wrtag_y[27:0];
4766 if (`SPC4.lsu.dta.wr_way[3])
4767 dta_way3[`SPC4.lsu.dta.index_y[6:0]] <= `SPC4.lsu.dta.wrtag_y[27:0];
4768end // always }
4769
4770//----------------------------------------------------------
4771`endif
4772endmodule
4773
4774`endif
4775`ifdef CORE_5
4776
4777module ldst_lsu_c5 ();
4778`ifndef GATESIM
4779
4780// common defines
4781`include "defines.vh"
4782`include "nas.vh"
4783// PCX/CPX packet defines (see :/verif/env/common/vera/include)
4784`include "ccx.vri"
4785`include "cmp.vri"
4786
4787//---------------------
4788// Load Signals
4789wire load_w;
4790
4791wire ldi_suppress;
4792wire [2:0] ldi_tid_w;
4793wire [5:0] ldi_tnum_w;
4794wire [39:0] ldi_pa_b;
4795reg [39:0] ldi_pa_w;
4796wire [1:0] ldi_size_b;
4797reg [1:0] ldi_size_w;
4798wire ldi_bld_b;
4799wire ldi_qld_b;
4800wire ldi_ldbl_b;
4801wire ldi_ldd_b;
4802wire ldi_atomic_b;
4803wire ldi_pf_b;
4804reg ldi_pf_w;
4805reg [7:0] ldi_itype_w;
4806reg [7:0] dsrc;
4807
4808wire ld_miss_b;
4809reg ld_miss_w;
4810reg stb_hit_w;
4811wire fraw_w;
4812wire hit_w;
4813wire miss_w;
4814wire load_data_hit;
4815
4816wire load_fill_e;
4817reg load_fill_m;
4818reg load_fill_b;
4819reg load_fill_w;
4820wire [2:0] ldf_tid_e;
4821reg [2:0] ldf_tid_m;
4822reg [2:0] ldf_tid_b;
4823reg [2:0] ldf_tid_w;
4824reg [5:0] ldf_tnum_w;
4825wire [39:0] ldf_pa_e;
4826reg [39:0] ldf_pa_m;
4827reg [39:0] ldf_pa_b;
4828reg [39:0] ldf_pa_w;
4829
4830//---------------------
4831// Store Signals
4832wire unflushed_store_w;
4833wire store_w;
4834wire sti_suppress;
4835wire [2:0] sti_tid_b;
4836reg [2:0] sti_tid_w;
4837wire [5:0] sti_tnum_w;
4838wire [39:0] sti_pa_b;
4839reg [39:0] sti_pa_w;
4840wire [63:0] sti_data_w;
4841wire [7:0] sti_size_m;
4842reg [7:0] sti_size_b;
4843reg [7:0] sti_size_w;
4844wire [7:0] sti_itype_w;
4845reg [7:0] itype_w;
4846wire [63:0] sbd_st_data_b;
4847reg [63:0] sbd_st_data_w;
4848wire flip_size_b;
4849
4850wire atomic_b;
4851wire rmo_st_b;
4852wire blk_inst_b;
4853reg blk_inst_w;
4854
4855wire bst_in_prog_b;
4856reg bst_in_prog_w;
4857wire [39:0] bst_pa_b;
4858reg [39:0] bst_pa_w;
4859wire [2:0] bst_tid_b;
4860reg [2:0] bst_tid_w;
4861wire [39:0] st_pa_b;
4862reg [39:0] st_pa_w;
4863wire [2:0] st_tid_b;
4864reg [2:0] st_tid_w;
4865
4866wire store_inv_e;
4867reg store_inv_m;
4868reg store_inv_b;
4869reg store_inv_w;
4870wire [5:0] stinv_tnum_e;
4871reg [5:0] stinv_tnum_m;
4872reg [5:0] stinv_tnum_b;
4873reg [5:0] stinv_tnum_w;
4874
4875wire store_update_e;
4876reg store_update_m;
4877reg store_update_b;
4878reg store_update_w;
4879wire [2:0] stu_tid_e;
4880reg [2:0] stu_tid_m;
4881reg [2:0] stu_tid_b;
4882reg [2:0] stu_tid_w;
4883wire [5:0] stu_tnum_e;
4884reg [5:0] stu_tnum_m;
4885reg [5:0] stu_tnum_b;
4886reg [5:0] stu_tnum_w;
4887
4888wire [7:0] asi_st_dequeue;
4889wire [7:0] st_ack_no_asi_e;
4890reg [7:0] st_ack_no_asi_m;
4891reg [7:0] st_ack_no_asi_b;
4892wire [7:0] store_ack_b;
4893reg [7:0] store_ack_w;
4894wire [7:0] st_ack_rmo_b;
4895reg [7:0] st_ack_rmo_w;
4896reg sta_rmo;
4897reg [2:0] sta_tid;
4898reg [5:0] sta_tnum;
4899reg sta_suppress [0:7]; // 1 per thread
4900wire st_io_asi;
4901wire [2:0] st_io_tid;
4902wire [7:0] st_data_access_e;
4903reg [7:0] st_data_access_m;
4904reg [7:0] st_data_access_b;
4905reg [7:0] st_data_access_w;
4906reg [2:0] tmp_tid;
4907reg [5:0] tmp_tnum;
4908
4909reg [39:0] store_pa_m;
4910reg [39:0] store_pa_b;
4911reg [39:0] store_pa_w;
4912
4913wire [1:0] l1_way_select;
4914wire [6:0] l1_index;
4915wire [27:0] my_way;
4916wire [27:0] way0;
4917wire [27:0] way1;
4918wire [27:0] way2;
4919wire [27:0] way3;
4920
4921wire [3:0] evict_inv_e;
4922reg [3:0] evict_inv_m;
4923reg [3:0] evict_inv_b;
4924reg [3:0] evict_inv_w;
4925wire [2:0] evict_srcid_e;
4926reg [2:0] evict_srcid_m;
4927reg [2:0] evict_srcid_b;
4928reg [2:0] evict_srcid_w;
4929
4930wire [8:0] pcx_req;
4931reg [8:0] pcx_req_1;
4932wire [129:0] pcx_data;
4933
4934wire perfmon;
4935wire perfmon_g;
4936reg perfmon_m;
4937reg perfmon_b;
4938reg perfmon_w;
4939wire [2:0] perfmon_tid;
4940wire [2:0] perfmon_tid_g;
4941reg [2:0] perfmon_tid_m;
4942reg [2:0] perfmon_tid_b;
4943reg [2:0] perfmon_tid_w;
4944wire [5:0] perfmon_tnum;
4945wire [7:0] perfmon_mask;
4946wire [7:0] perfmon_mask_g;
4947reg [7:0] perfmon_mask_m;
4948reg [7:0] perfmon_mask_b;
4949reg [7:0] perfmon_mask_w;
4950
4951wire [7:0] bst_kill;
4952reg [2:0] bst_kill_tid;
4953reg [5:0] bst_kill_tnum;
4954
4955wire [7:0] stb_state0_m;
4956wire [7:0] stb_state1_m;
4957wire [7:0] stb_state2_m;
4958wire [7:0] stb_state3_m;
4959wire [7:0] stb_state4_m;
4960wire [7:0] stb_state5_m;
4961wire [7:0] stb_state6_m;
4962wire [7:0] stb_state7_m;
4963reg [7:0] stb_state0_b;
4964reg [7:0] stb_state1_b;
4965reg [7:0] stb_state2_b;
4966reg [7:0] stb_state3_b;
4967reg [7:0] stb_state4_b;
4968reg [7:0] stb_state5_b;
4969reg [7:0] stb_state6_b;
4970reg [7:0] stb_state7_b;
4971reg [7:0] stb_state0_w;
4972reg [7:0] stb_state1_w;
4973reg [7:0] stb_state2_w;
4974reg [7:0] stb_state3_w;
4975reg [7:0] stb_state4_w;
4976reg [7:0] stb_state5_w;
4977reg [7:0] stb_state6_w;
4978reg [7:0] stb_state7_w;
4979reg [7:0] stb_state;
4980reg stb_last;
4981
4982// Copy of dtag
4983reg [27:0] dta_way0 [127:0];
4984reg [27:0] dta_way1 [127:0];
4985reg [27:0] dta_way2 [127:0];
4986reg [27:0] dta_way3 [127:0];
4987
4988//---------------------
4989// Misc Signals
4990wire [2:0] mycid;
4991integer tstamp;
4992integer junk;
4993integer i;
4994
4995initial begin // {
4996 ldf_tnum_w = 6'b0;
4997 dsrc = 2'b0;
4998 sta_tid = 3'b0;
4999 sta_tnum = 6'b0;
5000 for (i=0; i<=7; i=i+1) begin
5001 sta_suppress[i] = 1'b0;
5002 end
5003
5004end // }
5005
5006// for debug only - allows display in Debussy
5007wire sta_suppress0;
5008wire sta_suppress1;
5009wire sta_suppress2;
5010wire sta_suppress3;
5011wire sta_suppress4;
5012wire sta_suppress5;
5013wire sta_suppress6;
5014wire sta_suppress7;
5015
5016 assign sta_suppress0 = sta_suppress[0];
5017 assign sta_suppress1 = sta_suppress[1];
5018 assign sta_suppress2 = sta_suppress[2];
5019 assign sta_suppress3 = sta_suppress[3];
5020 assign sta_suppress4 = sta_suppress[4];
5021 assign sta_suppress5 = sta_suppress[5];
5022 assign sta_suppress6 = sta_suppress[6];
5023 assign sta_suppress7 = sta_suppress[7];
5024
5025//----------------------------------------------------------
5026//----------------------------------------------------------
5027// DUT probes
5028
5029 assign mycid = 5;
5030
5031//---------------------
5032// Load Issue
5033
5034 // If Load to IO ASIs, load issue should not be sent.
5035 // In this case, asi_internal_w is asserted and will suppress load_w.
5036
5037 assign load_w = `SPC5.lsu.dcc.ld_inst_vld_w &
5038 ~`PROBES5.asi_internal_w &
5039 ~`SPC5.lsu.dcc.flush_w &
5040 ~ldi_pf_w;
5041
5042 // ldxa to IO ASI are already suppressed since load_w will not assert.
5043 // ldi_suppress is required to also suppress normal ld to IO ASI address range.
5044 assign ldi_suppress = (ldi_pa_w[39:32] == `IO_ASI_ADDR);
5045
5046 assign ldi_tid_w = `SPC5.lsu.dcc.tid_w;
5047 assign ldi_tnum_w = {mycid,ldi_tid_w};
5048 assign ldi_size_b = `SPC5.lsu.dcc.ldst_sz_b; // 2 bits
5049 assign ldi_atomic_b = `SPC5.lsu.dcc.atomic_b;
5050 assign ldi_qld_b = `SPC5.lsu.dcc.quad_ldd_b;
5051 assign ldi_ldbl_b = `SPC5.lsu.dcc_ldbl_b;
5052 assign ldi_ldd_b = ldi_ldbl_b & !ldi_qld_b;
5053 assign ldi_bld_b = `SPC5.lsu.dcc.dcc_blk_inst_b;
5054 assign ldi_pf_b = `SPC5.lsu.dcc.pref_inst_b;
5055
5056 // pa, tid are same for LoadIssue and StoreIssue
5057 assign ldi_pa_b = {`SPC5.lsu.tlb_pgnum[39:13],
5058 `SPC5.lsu.lmd.lsu_va_b[12:0]};
5059
5060//---------------------
5061// Load Fill
5062
5063 assign load_fill_e = `SPC5.lsu.dcc.ld_fill_e;
5064 assign ldf_tid_e = `SPC5.lsu.cid.cid_tid;
5065 assign ldf_pa_e = {`SPC5.lsu.lmd.lmd_fill_addr_e[39:3],3'b0};
5066
5067//---------------------
5068// Store Issue
5069
5070 // blk_inst_w will suppress store_w for 1st of 9 cycles on block store.
5071
5072 // If Store to IO ASIs, store issue should not be sent.
5073 // In this case, asi_internal_w is asserted and will suppress store_w.
5074
5075 assign unflushed_store_w = `SPC5.lsu.sbc.unflushed_store_w;
5076
5077 assign store_w = unflushed_store_w &
5078 (~(`PROBES5.asi_internal_w | blk_inst_w) |
5079 bst_in_prog_w);
5080
5081 assign atomic_b = `SPC5.lsu.dcc.atomic_b;
5082 assign rmo_st_b = `SPC5.lsu.sbc_rmo_st_b;
5083 assign blk_inst_b = `SPC5.lsu.dcc.dcc_blk_inst_b;
5084
5085 assign sti_tnum_w = {mycid,sti_tid_w};
5086 assign sti_size_m = `SPC5.lsu.dcc_ldst_bmask;
5087
5088 // flip_size will assert if endian swap for partial store is needed
5089 assign flip_size_b = `SPC5.lsu.dcc.pst_asi_b & `SPC5.lsu.dcc.tlb_tte_ie_b & `SPC5.lsu.dcc.tlb_tte_vld_b & `SPC5.lsu.dcc.st_inst_vld_b;
5090
5091 // Change itype only when control signals are valid
5092 assign sti_itype_w = unflushed_store_w ? itype_w : sti_itype_w;
5093
5094 // It is correct to mix W & B stage signals for this.
5095 // STD is a 2 cycle instruction.
5096 // inst valid in W, data in B (1 cycle behind)
5097 assign sti_data_w = `SPC5.lsu.sbc.std_inst_w ?
5098 sbd_st_data_b :
5099 sbd_st_data_w;
5100 assign sbd_st_data_b = `SPC5.lsu.sbd_st_data_b;
5101
5102 // Use different pa,tid if block store
5103 assign sti_pa_b = bst_in_prog_b ? bst_pa_b : st_pa_b;
5104 assign sti_tid_b = bst_in_prog_b ? bst_tid_b : st_tid_b;
5105
5106 // stxa to IO ASI are already suppressed since store_w will not assert.
5107 // sti_suppress is required to also suppress normal st to IO ASI address range.
5108 assign sti_suppress = (sti_pa_w[39:32] == `IO_ASI_ADDR);
5109
5110 // Normal Store
5111 assign st_pa_b = {`SPC5.lsu.tlb_pgnum[39:13],
5112 `SPC5.lsu.lmd.lsu_va_b[12:0]};
5113 assign st_tid_b = `SPC5.lsu.dcc.tid_b;
5114
5115 // Block Store
5116 assign bst_in_prog_b = `SPC5.lsu.sbc.bst_in_prog_b;
5117 assign bst_pa_b = {`SPC5.lsu.sbd.st_addr_b[39:3],3'b0};
5118 assign bst_tid_b = `SPC5.lsu.sbc.bst_tid;
5119
5120//---------------------
5121// Store Ack
5122
5123assign asi_st_dequeue[7:0] = `SPC5.lsu.dcc_asi_rtn_vld[7:0] &
5124 {8{~`SPC5.lsu.dcc_asi_rtn_rd}};
5125
5126 assign st_ack_no_asi_e = `SPC5.lsu.cic.cic_st_dequeue[7:0] &
5127 ~asi_st_dequeue[7:0] &
5128 ~`SPC5.lsu.cic.sbc_bst_sel[7:0];
5129
5130 assign st_ack_rmo_b = {`SPC5.lsu.sbs7.rmo_st_commit_p4,
5131 `SPC5.lsu.sbs6.rmo_st_commit_p4,
5132 `SPC5.lsu.sbs5.rmo_st_commit_p4,
5133 `SPC5.lsu.sbs4.rmo_st_commit_p4,
5134 `SPC5.lsu.sbs3.rmo_st_commit_p4,
5135 `SPC5.lsu.sbs2.rmo_st_commit_p4,
5136 `SPC5.lsu.sbs1.rmo_st_commit_p4,
5137 `SPC5.lsu.sbs0.rmo_st_commit_p4
5138 };
5139
5140 // It is possible to see 2 threads store_ack in same cycle
5141 // (1 st_ack_no_asi & 1 st_ack_rmo)
5142
5143 assign store_ack_b = st_ack_no_asi_b | st_ack_rmo_b;
5144
5145 // cic_st_atm_cmplt is atomic store completing (same time as store ack)
5146 // (lsu.lmc.dcl2u_err | dcl2nd_err) indicate a data_access_error condition
5147 assign st_data_access_e = {8{(`SPC5.lsu.cic.cic_st_atm_cmplt &
5148 (`SPC5.lsu.lmc.dcl2u_err | `SPC5.lsu.lmc.dcl2nd_err))}} &
5149 `SPC5.lsu.cic.cic_st_dequeue[7:0];
5150//---------------------
5151// Store Inv
5152
5153 // Same as evict_inv_e but with cpq_evict deasserted
5154 assign store_inv_e = `SPC5.lsu.cic_invalidate_e &
5155 (`SPC5.lsu.cic_inv_wen_e!=0)&
5156 ~`SPC5.lsu.cic.cpq_evict &
5157 ~`SPC5.lsu.cic.cid_set_inval &
5158 ~`SPC5.lsu.cic.cic_xinval_e &
5159 ~(`SPC5.lsu.cic.cid_pkt_type[4:0] == 5'b10110);
5160 assign stinv_tnum_e =
5161 {`SPC5.lsu.cid.cpq_data_out[`CPX_VACK_CID],
5162 `SPC5.lsu.cid.cid_tid};
5163
5164//---------------------
5165// Store Update
5166
5167 assign store_update_e = `SPC5.lsu.cic_st_update_e;
5168 assign stu_tid_e = `SPC5.lsu.cid.cid_tid;
5169 assign stu_tnum_e = {mycid,stu_tid_e};
5170
5171 assign l1_index = {`SPC5.lsu.cid.cpq_data_out[116],
5172 `SPC5.lsu.cid.cpq_data_out[115],
5173 `SPC5.lsu.cid.cpq_data_out[114],
5174 `SPC5.lsu.cid.cpq_data_out[113],
5175 `SPC5.lsu.cid.cpq_data_out[112],
5176 `SPC5.lsu.cid.cpq_data_out[122],
5177 `SPC5.lsu.cid.cpq_data_out[121]
5178 };
5179 assign l1_way_select = `SPC5.lsu.cid_inv_vec[17:16];
5180
5181//---------------------
5182// EvictInv
5183
5184 // Same as store_inv_e but with cpq_evict asserted
5185 // LSU can invalidate 1-4 Dcache lines
5186 assign evict_inv_e[3:0] = {4{`SPC5.lsu.cic_invalidate_e & // enable for 4 bit wen below
5187 (`SPC5.lsu.cic_inv_wen_e!=0)&
5188 `SPC5.lsu.cic.cpq_evict &
5189 ~`SPC5.lsu.cic.cid_set_inval &
5190 ~`SPC5.lsu.cic.cic_xinval_e}} &
5191
5192 {|(`SPC5.lsu.cic.evict_inv_wen[15:12]), // 4 bit field - 1 hot. Send evinv when any one set.
5193 |(`SPC5.lsu.cic.evict_inv_wen[11:8]),
5194 |(`SPC5.lsu.cic.evict_inv_wen[7:4]),
5195 |(`SPC5.lsu.cic.evict_inv_wen[3:0])
5196 };
5197
5198 assign evict_srcid_e = `SPC5.lsu.cid.cpq_data_out[114:112];
5199
5200
5201//---------------------
5202// Detect Store to IO ASI in PCX crossbar packet.
5203// This causes next Store Ack to be suppressed.
5204
5205// Normal Store only since atomics are always to cacheable space
5206
5207// Trigger on Store to crossbar.
5208// If Store request is retried on crossbar (due to no grant),
5209// then, st_io_asi will fire multiple times for the same request.
5210// This is OK because it just causes sta_suppress to be set multiple times.
5211
5212 assign pcx_req = `SPC5.spc_pcx_req_pq;
5213 assign pcx_data = `SPC5.spc_pcx_data_pa;
5214
5215 assign st_io_asi = (pcx_req_1 != 9'b0) &
5216 (pcx_data [`PCX_VALID]==1'b1) &
5217 (pcx_data [`PCX_RQTYP]==`CCX_REQ_ST) &
5218 (pcx_data [103:96]==`IO_ASI_ADDR); // Upper byte of 40 bit addr
5219
5220 assign st_io_tid = pcx_data [`PCX_TID];
5221
5222 assign stb_state0_m = `SPC5.lsu.sbs0.stb_state_vld[7:0];
5223 assign stb_state1_m = `SPC5.lsu.sbs1.stb_state_vld[7:0];
5224 assign stb_state2_m = `SPC5.lsu.sbs2.stb_state_vld[7:0];
5225 assign stb_state3_m = `SPC5.lsu.sbs3.stb_state_vld[7:0];
5226 assign stb_state4_m = `SPC5.lsu.sbs4.stb_state_vld[7:0];
5227 assign stb_state5_m = `SPC5.lsu.sbs5.stb_state_vld[7:0];
5228 assign stb_state6_m = `SPC5.lsu.sbs6.stb_state_vld[7:0];
5229 assign stb_state7_m = `SPC5.lsu.sbs7.stb_state_vld[7:0];
5230
5231//---------------------
5232// Load Data (hit only) (See ldst_l2.v for Load Data - miss)
5233
5234 assign load_data_hit = load_w && (hit_w | fraw_w);
5235 assign ld_miss_b = `SPC5.lsu.dcc.dcc_ld_miss_b;
5236 assign fraw_w = `SPC5.lsu.lmc.ld_raw_bypass_w;
5237 assign hit_w = ~ld_miss_w & ~stb_hit_w;
5238 assign miss_w = ~fraw_w & (ld_miss_w | stb_hit_w);
5239
5240//---------------------
5241// Load Pop
5242
5243 assign perfmon_g = `SPC5.lsu.lsu_perfmon_trap_g;
5244 assign perfmon_tid_g = `SPC5.lsu.lsu_dcerr_tid_g;
5245 // perfmon_mask will not fire if trap is not enabled or higher priority trap is taken.
5246 assign perfmon_mask_g = {`SPC5.tlu.fls1.pil_mask_15[3:0], `SPC5.tlu.fls0.pil_mask_15[3:0]} &
5247 ~{8 {`SPC5.lsu_dcl2u_err_g | `SPC5.lsu_dcl2nd_err_g}};
5248
5249 assign perfmon = perfmon_w;
5250 assign perfmon_tid = perfmon_tid_w;
5251 assign perfmon_tnum = {mycid,perfmon_tid_w};
5252 assign perfmon_mask = perfmon_mask_w;
5253
5254
5255
5256//---------------------
5257// Store Pop
5258
5259 assign bst_kill = {`SPC5.lsu.sbs7.bst_kill,
5260 `SPC5.lsu.sbs6.bst_kill,
5261 `SPC5.lsu.sbs5.bst_kill,
5262 `SPC5.lsu.sbs4.bst_kill,
5263 `SPC5.lsu.sbs3.bst_kill,
5264 `SPC5.lsu.sbs2.bst_kill,
5265 `SPC5.lsu.sbs1.bst_kill,
5266 `SPC5.lsu.sbs0.bst_kill};
5267
5268//----------------------------------------------------------
5269//----------------------------------------------------------
5270
5271always @ (posedge `SPC5.l2clk) begin // {
5272
5273 tstamp = `TOP.core_cycle_cnt - 1;
5274
5275 //------------------------------
5276 // Pipeline from B to W
5277
5278 ldi_pa_w <= ldi_pa_b;
5279 ld_miss_w <= ld_miss_b;
5280 stb_hit_w <= `SPC5.lsu.stb_cam_hit;
5281 ldi_pf_w <= ldi_pf_b;
5282 ldi_size_w <= ldi_size_b;
5283 load_fill_m <= load_fill_e;
5284 load_fill_b <= load_fill_m;
5285 load_fill_w <= load_fill_b;
5286 ldf_tid_m <= ldf_tid_e;
5287 ldf_tid_b <= ldf_tid_m;
5288 ldf_tid_w <= ldf_tid_b;
5289 ldf_pa_m <= ldf_pa_e;
5290 ldf_pa_b <= ldf_pa_m;
5291 ldf_pa_w <= ldf_pa_b;
5292
5293 sti_size_b <= sti_size_m;
5294 sti_size_w <= (flip_size_b) ? {sti_size_b[0],sti_size_b[1],sti_size_b[2],sti_size_b[3],
5295 sti_size_b[4],sti_size_b[5],sti_size_b[6],sti_size_b[7]}
5296 : sti_size_b;
5297 sti_pa_w <= sti_pa_b;
5298 sti_tid_w <= sti_tid_b;
5299 st_ack_no_asi_m <= st_ack_no_asi_e;
5300 st_ack_no_asi_b <= st_ack_no_asi_m;
5301 st_data_access_m <= st_data_access_e;
5302 st_data_access_b <= st_data_access_m;
5303 st_data_access_w <= st_data_access_b;
5304 store_ack_w <= store_ack_b;
5305 store_update_m <= store_update_e;
5306 store_update_b <= store_update_m;
5307 store_update_w <= store_update_b;
5308 store_inv_m <= store_inv_e;
5309 store_inv_b <= store_inv_m;
5310 store_inv_w <= store_inv_b;
5311 stinv_tnum_m <= stinv_tnum_e;
5312 stinv_tnum_b <= stinv_tnum_m;
5313 stinv_tnum_w <= stinv_tnum_b;
5314 st_ack_rmo_w <= st_ack_rmo_b;
5315 stu_tid_m <= stu_tid_e;
5316 stu_tid_b <= stu_tid_m;
5317 stu_tid_w <= stu_tid_b;
5318 stu_tnum_m <= stu_tnum_e;
5319 stu_tnum_b <= stu_tnum_m;
5320 stu_tnum_w <= stu_tnum_b;
5321 store_pa_b <= store_pa_m;
5322 store_pa_w <= store_pa_b;
5323 bst_in_prog_w <= bst_in_prog_b;
5324 blk_inst_w <= blk_inst_b;
5325 sbd_st_data_w <= sbd_st_data_b;
5326 evict_inv_m <= evict_inv_e;
5327 evict_inv_b <= evict_inv_m;
5328 evict_inv_w <= evict_inv_b;
5329 evict_srcid_m <= evict_srcid_e;
5330 evict_srcid_b <= evict_srcid_m;
5331 evict_srcid_w <= evict_srcid_b;
5332 pcx_req_1 <= pcx_req;
5333 stb_state0_b <= stb_state0_m;
5334 stb_state1_b <= stb_state1_m;
5335 stb_state2_b <= stb_state2_m;
5336 stb_state3_b <= stb_state3_m;
5337 stb_state4_b <= stb_state4_m;
5338 stb_state5_b <= stb_state5_m;
5339 stb_state6_b <= stb_state6_m;
5340 stb_state7_b <= stb_state7_m;
5341 stb_state0_w <= stb_state0_b;
5342 stb_state1_w <= stb_state1_b;
5343 stb_state2_w <= stb_state2_b;
5344 stb_state3_w <= stb_state3_b;
5345 stb_state4_w <= stb_state4_b;
5346 stb_state5_w <= stb_state5_b;
5347 stb_state6_w <= stb_state6_b;
5348 stb_state7_w <= stb_state7_b;
5349
5350 perfmon_m <= perfmon_g;
5351 perfmon_b <= perfmon_m;
5352 perfmon_w <= perfmon_b;
5353 perfmon_tid_m <= perfmon_tid_g;
5354 perfmon_tid_b <= perfmon_tid_m;
5355 perfmon_tid_w <= perfmon_tid_b;
5356 perfmon_mask_m <= perfmon_mask_g;
5357 perfmon_mask_b <= perfmon_mask_m;
5358 perfmon_mask_w <= perfmon_mask_b;
5359
5360 //----------------------------------------------------------
5361 // Calculate pa for STUPDATE and STINV
5362 // Moved this into the always block to avoid the constant
5363 // probing of the dtag memory structure.
5364
5365 if (store_inv_e | store_update_e) begin // {
5366 store_pa_m[2:0] <= 3'b000;
5367 store_pa_m[10:3] <= {`SPC5.lsu.cid.cpq_data_out[116],
5368 `SPC5.lsu.cid.cpq_data_out[115],
5369 `SPC5.lsu.cid.cpq_data_out[114],
5370 `SPC5.lsu.cid.cpq_data_out[113],
5371 `SPC5.lsu.cid.cpq_data_out[112],
5372 `SPC5.lsu.cid.cpq_data_out[122],
5373 `SPC5.lsu.cid.cpq_data_out[121],
5374 `SPC5.lsu.cid.cpq_data_out[104]
5375 };
5376 store_pa_m[38:11] <= (l1_way_select==2'h0) ? dta_way0[l1_index] :
5377 (l1_way_select==2'h1) ? dta_way1[l1_index] :
5378 (l1_way_select==2'h2) ? dta_way2[l1_index] : dta_way3[l1_index];
5379 store_pa_m[39] <= 1'b0; // Only memory stores get inv/update
5380 end // }
5381
5382
5383 // After Store to IO ASI is detected at StI time, suppress the next Store Ack
5384 // There is only 1 store to IO ASI active at one time per thread because
5385 // that is all the LSU allows.
5386 if (st_io_asi) begin
5387 sta_suppress [st_io_tid] <= 1'b1;
5388 end
5389
5390 case ({ldi_atomic_b,ldi_bld_b,ldi_ldd_b,ldi_qld_b,ldi_pf_b})
5391 5'b00000: ldi_itype_w <= `ITYPE_LOAD;
5392 5'b00001: ldi_itype_w <= `ITYPE_PREFETCH;
5393 5'b00010: ldi_itype_w <= `ITYPE_QUAD_LOAD;
5394 5'b00100: ldi_itype_w <= `ITYPE_DOUBLE_LOAD;
5395 5'b01000: ldi_itype_w <= `ITYPE_BLOCK_LOAD;
5396 5'b10000: ldi_itype_w <= `ITYPE_ATOMIC;
5397 default: ldi_itype_w <= `ITYPE_NO; // Illegal
5398 endcase
5399
5400 case ({atomic_b,rmo_st_b,bst_in_prog_b})
5401 3'b000: itype_w <= `ITYPE_STORE;
5402 3'b010: itype_w <= `ITYPE_BLK_INIT_ST;
5403 3'b011: itype_w <= `ITYPE_BLOCK_STORE;
5404 3'b100: itype_w <= `ITYPE_ATOMIC;
5405 3'b001,
5406 3'b101,
5407 3'b110,
5408 3'b111: itype_w <= `ITYPE_NO; // Illegal
5409 endcase
5410
5411 //----------------------------------------------------------
5412 //----------------------------------------------------------
5413 // Load Issue
5414
5415 // Load Issue must be before Store Issue for atomic
5416
5417 if (load_w) begin // {
5418
5419 if (ldi_suppress==1'b0) begin // {
5420 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
5421 `PR_INFO ("pli_ldst", `INFO,
5422 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h size=%h typ=%0h ts=%0d",
5423 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
5424 junk = $sim_send(`PLI_MEM_LD_ISSUE,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
5425 end // }
5426 end // }
5427 else begin // {
5428 `PR_INFO ("pli_ldst", `INFO,
5429 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h Suppress for IO ASI",mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w);
5430 end // }
5431
5432 if (`PARGS.show_memop_on) begin // {
5433 `PR_NORMAL ("pli_ldst", `NORMAL,
5434 "C%0d T%0d MEMOP_LOAD tid=%d pa=%h ts=%0d (LSU - W stage)",
5435 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,tstamp);
5436 end // }
5437
5438 end // }
5439
5440 //----------------------------------------------------------
5441 //----------------------------------------------------------
5442 // Load Data (hit only) (See ldst_l2.v for Load Data - miss)
5443
5444 if (load_data_hit) begin // {
5445
5446 dsrc = hit_w ? `DSRC_L1 : `DSRC_STB;
5447
5448 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
5449 `PR_INFO ("pli_ldst", `INFO,
5450 "C%0d T%0d PLI_MEM_LDDATA tid=%d pa=%h dsrc=%0h ts=%0d",
5451 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
5452 junk = $sim_send(`PLI_MEM_LD_DATA,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
5453 end // }
5454
5455 end // }
5456
5457
5458 //----------------------------------------------------------
5459 //----------------------------------------------------------
5460 // Store Ack
5461 //
5462 // Store Ack cmd must be sent before Store Inv, Store Update for NAS
5463 // Store Ack & Store Update will be in the same timestamp
5464
5465 if (store_ack_w != 8'b0) begin // {
5466
5467 for (i=0; i<=7; i=i+1) begin // {
5468 if (store_ack_w[i]) begin // {
5469 sta_tid = i[2:0];
5470 sta_tnum = {mycid,sta_tid};
5471 sta_rmo = st_ack_rmo_w[i];
5472
5473 if (sta_suppress[sta_tid]==1'b0) begin // {
5474 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
5475 `PR_INFO ("pli_ldst", `INFO,
5476 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
5477 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
5478 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
5479 end // }
5480 end // }
5481
5482 else begin // {
5483
5484 // It is possible for 2 Stores it be in flight because of the delay from CPQ push & pop.
5485 // So, make sure Bench is suppressing the correct Store.
5486 case (sta_tid)
5487 3'h0: stb_state=stb_state0_w;
5488 3'h1: stb_state=stb_state1_w;
5489 3'h2: stb_state=stb_state2_w;
5490 3'h3: stb_state=stb_state3_w;
5491 3'h4: stb_state=stb_state4_w;
5492 3'h5: stb_state=stb_state5_w;
5493 3'h6: stb_state=stb_state6_w;
5494 3'h7: stb_state=stb_state7_w;
5495 default:
5496 `PR_ERROR ("pli_ldst", `ERROR,
5497 "C%0d T%0d PLI_MEM_XXX Bench Error. Should never execute case default",mycid,sta_tid);
5498 endcase
5499
5500 // If stb_state has only 1 bit asserted, then suppress the STACK. Otherwise, send the STACK.
5501 case (stb_state) // {
5502 8'b0000_0000: begin
5503 `PR_ERROR ("pli_ldst", `ERROR,
5504 "C%0d T%0d PLI_MEM_XXX Bench Error. stb_state should not be 8'b0",
5505 mycid,sta_tid);
5506 end
5507 8'b0000_0001,
5508 8'b0000_0010,
5509 8'b0000_0100,
5510 8'b0000_1000,
5511 8'b0001_0000,
5512 8'b0010_0000,
5513 8'b0100_0000,
5514 8'b1000_0000: stb_last = 1'b1;
5515 default: stb_last = 1'b0;
5516 endcase // }
5517
5518 if (stb_last==1'b0) begin // {
5519 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
5520 `PR_INFO ("pli_ldst", `INFO,
5521 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
5522 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
5523 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
5524 end // }
5525 end // }
5526 else begin // {
5527 sta_suppress[sta_tid] <= 1'b0;
5528 `PR_INFO ("pli_ldst", `INFO,
5529 "C%0d T%0d PLI_MEM_STACK tid=%d Suppress for IO ASI",mycid,sta_tid,sta_tnum);
5530 end // }
5531 end // }
5532
5533 end // if (store_ack_w[i]) }
5534 end // for }
5535
5536 end // if (store_ack_w) }
5537
5538 //----------------------------------------------------------
5539 //----------------------------------------------------------
5540 // Store Inv
5541
5542 if (store_inv_w) begin // {
5543
5544 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stinv_tnum_w]) begin // {
5545 `PR_INFO ("pli_ldst", `INFO,
5546 "C%0d PLI_MEM_STINV tid=%d pa=%h cid=%h ts=%0d",
5547 mycid,stinv_tnum_w,store_pa_w,mycid,tstamp);
5548 junk = $sim_send(`PLI_MEM_ST_INV,mycid,stinv_tnum_w,store_pa_w,tstamp);
5549 end // }
5550
5551 end // }
5552
5553
5554 //----------------------------------------------------------
5555 //----------------------------------------------------------
5556 // Store Update
5557
5558 if (store_update_w) begin // {
5559
5560 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stu_tnum_w]) begin // {
5561 `PR_INFO ("pli_ldst", `INFO,
5562 "C%0d T%0d PLI_MEM_STUP tid=%d pa=%h ts=%0d",
5563 mycid,stu_tid_w,stu_tnum_w,store_pa_w,tstamp);
5564 junk = $sim_send(`PLI_MEM_ST_UPDATE,stu_tnum_w,store_pa_w,tstamp);
5565 end // }
5566
5567 end // }
5568
5569 //----------------------------------------------------------
5570 //----------------------------------------------------------
5571 // Load Fill
5572
5573 if (load_fill_w) begin // {
5574
5575 ldf_tnum_w = {mycid,ldf_tid_w};
5576
5577 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldf_tnum_w]) begin // {
5578 `PR_INFO ("pli_ldst", `INFO,
5579 "C%0d T%0d PLI_MEM_LDFILL tid=%d pa=%h ts=%0d",
5580 mycid,ldf_tid_w,ldf_tnum_w,ldf_pa_w,tstamp);
5581 junk = $sim_send(`PLI_MEM_LD_FILL,ldf_tnum_w,ldf_pa_w,tstamp);
5582 end // }
5583
5584 end // }
5585
5586 //----------------------------------------------------------
5587 //----------------------------------------------------------
5588 // Store Issue
5589
5590 if (store_w) begin // {
5591
5592 if (sti_suppress==1'b0) begin // {
5593 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sti_tnum_w]) begin // {
5594 `PR_INFO ("pli_ldst", `INFO,
5595 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h data=%h sz=%h typ=%0h ts=%0d",
5596 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
5597 junk = $sim_send(`PLI_MEM_ST_ISSUE,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
5598 end // }
5599
5600 end // }
5601 else begin // {
5602 `PR_INFO ("pli_ldst", `INFO,
5603 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h Suppress for IO ASI",mycid,sti_tid_w,sti_tnum_w,sti_pa_w);
5604 end // }
5605
5606 if (`PARGS.show_memop_on) begin // {
5607 `PR_NORMAL ("pli_ldst", `NORMAL,
5608 "C%0d T%0d MEMOP_STORE tid=%d pa=%h data=%h sz=%h ts=%0d (LSU - W stage)",
5609 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,tstamp);
5610 end // }
5611
5612 end // }
5613
5614 //----------------------------------------------------------
5615 //----------------------------------------------------------
5616 // EvictInv
5617 // Send 1-4 EvictInv messages per cycle - based on how many Dcache lines were invalidated.
5618
5619 for (i=0; i<=3; i=i+1) begin // {
5620 if (evict_inv_w[i]) begin // {
5621
5622 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on) begin // {
5623 `PR_INFO ("pli_ldst", `INFO,
5624 "C%0d PLI_MEM_EVINV cid=%d srcid=%0d ts=%0d",
5625 mycid,mycid,evict_srcid_w,tstamp);
5626 junk = $sim_send(`PLI_MEM_EVICT_INV,mycid,evict_srcid_w,tstamp);
5627 end // }
5628
5629 end // }
5630 end // }
5631
5632 //----------------------------------------------------------
5633 //----------------------------------------------------------
5634 // Load Pop - special case
5635
5636 // This is required in case of a performance monitor trap due to L2 miss.
5637 // In this case, the trap is not indicated until after the Load pkt returns to the LSU.
5638 // ldst_sync has already sent LDISSUE and LDDATA to Riesling. But, the Load is not executed.
5639 // Load Pop tells Riesling to pop the LDISSUE,LDDATA off of its queues.
5640
5641 if (perfmon & perfmon_mask[perfmon_tid]) begin // {
5642
5643 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[perfmon_tnum]) begin // {
5644 `PR_INFO ("pli_ldst", `INFO,
5645 "C%0d T%0d PLI_MEM_LDPOP tid=%d ts=%0d",
5646 mycid,perfmon_tid,perfmon_tnum,tstamp);
5647 junk = $sim_send(`PLI_MEM_LD_POP,perfmon_tnum);
5648 end // }
5649
5650 end // }
5651
5652 //----------------------------------------------------------
5653 //----------------------------------------------------------
5654 // Store Pop - special cases
5655
5656 // This is required in case of a FRF error trap (internal_proc_error) on a Block Store.
5657 // In this case, the trap is not indicated until after the 8 STISSUE has been sent to Riesling.
5658 // But, the Store is not executed.
5659 // Store Pop tells Riesling to pop the 8 STISSUE off of its queues.
5660
5661 if (bst_kill!==8'b0) begin // {
5662
5663 for (i=0;i<=7;i=i+1) begin
5664 if (bst_kill[i]==1'b1) begin
5665 bst_kill_tid = i;
5666 bst_kill_tnum = {mycid,bst_kill_tid};
5667
5668 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[bst_kill_tnum]) begin // {
5669 `PR_INFO ("pli_ldst", `INFO,
5670 "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
5671 mycid,bst_kill_tid,bst_kill_tnum,tstamp);
5672 junk = $sim_send(`PLI_MEM_ST_POP,bst_kill_tnum);
5673 end // }
5674 end
5675 end
5676
5677 end // }
5678
5679 //--------------------
5680 // This is required for data_access_error on atomic. In this case, Riesling only cleans up the Load,
5681 // but doesn't know it is an atomic so Riesling doesn't clean up the store in its buffers.
5682 // The STPOP tells Riesling to clear the newest Store from the buffers.
5683 // It is possible to have older Stores in-flight but not newer Stores in-flight.
5684
5685// if (st_data_access_w != 8'b0) begin // {
5686//
5687// for (i=0; i<=7; i=i+1) begin // {
5688// if (st_data_access_w[i]) begin // {
5689// tmp_tid = i[2:0];
5690// tmp_tnum = {mycid,tmp_tid};
5691//
5692// if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[tmp_tnum]) begin // {
5693// `PR_INFO ("pli_ldst", `INFO,
5694// "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
5695// mycid,tmp_tid,tmp_tnum,tstamp);
5696// junk = $sim_send(`PLI_MEM_ST_POP,tmp_tnum);
5697// end // }
5698// end // } if st_data_access[i]
5699// end // } for
5700// end // } if st_data_access
5701
5702end // always }
5703
5704//----------------------------------------------------------
5705// Need to model the D arrays to get PA's for store updates and invalidates
5706
5707always @ (negedge `SPC5.l2clk) begin // {
5708 if (`SPC5.lsu.dta.wr_way[0])
5709 dta_way0[`SPC5.lsu.dta.index_y[6:0]] <= `SPC5.lsu.dta.wrtag_y[27:0];
5710 if (`SPC5.lsu.dta.wr_way[1])
5711 dta_way1[`SPC5.lsu.dta.index_y[6:0]] <= `SPC5.lsu.dta.wrtag_y[27:0];
5712 if (`SPC5.lsu.dta.wr_way[2])
5713 dta_way2[`SPC5.lsu.dta.index_y[6:0]] <= `SPC5.lsu.dta.wrtag_y[27:0];
5714 if (`SPC5.lsu.dta.wr_way[3])
5715 dta_way3[`SPC5.lsu.dta.index_y[6:0]] <= `SPC5.lsu.dta.wrtag_y[27:0];
5716end // always }
5717
5718//----------------------------------------------------------
5719`endif
5720endmodule
5721
5722`endif
5723`ifdef CORE_6
5724
5725module ldst_lsu_c6 ();
5726`ifndef GATESIM
5727
5728// common defines
5729`include "defines.vh"
5730`include "nas.vh"
5731// PCX/CPX packet defines (see :/verif/env/common/vera/include)
5732`include "ccx.vri"
5733`include "cmp.vri"
5734
5735//---------------------
5736// Load Signals
5737wire load_w;
5738
5739wire ldi_suppress;
5740wire [2:0] ldi_tid_w;
5741wire [5:0] ldi_tnum_w;
5742wire [39:0] ldi_pa_b;
5743reg [39:0] ldi_pa_w;
5744wire [1:0] ldi_size_b;
5745reg [1:0] ldi_size_w;
5746wire ldi_bld_b;
5747wire ldi_qld_b;
5748wire ldi_ldbl_b;
5749wire ldi_ldd_b;
5750wire ldi_atomic_b;
5751wire ldi_pf_b;
5752reg ldi_pf_w;
5753reg [7:0] ldi_itype_w;
5754reg [7:0] dsrc;
5755
5756wire ld_miss_b;
5757reg ld_miss_w;
5758reg stb_hit_w;
5759wire fraw_w;
5760wire hit_w;
5761wire miss_w;
5762wire load_data_hit;
5763
5764wire load_fill_e;
5765reg load_fill_m;
5766reg load_fill_b;
5767reg load_fill_w;
5768wire [2:0] ldf_tid_e;
5769reg [2:0] ldf_tid_m;
5770reg [2:0] ldf_tid_b;
5771reg [2:0] ldf_tid_w;
5772reg [5:0] ldf_tnum_w;
5773wire [39:0] ldf_pa_e;
5774reg [39:0] ldf_pa_m;
5775reg [39:0] ldf_pa_b;
5776reg [39:0] ldf_pa_w;
5777
5778//---------------------
5779// Store Signals
5780wire unflushed_store_w;
5781wire store_w;
5782wire sti_suppress;
5783wire [2:0] sti_tid_b;
5784reg [2:0] sti_tid_w;
5785wire [5:0] sti_tnum_w;
5786wire [39:0] sti_pa_b;
5787reg [39:0] sti_pa_w;
5788wire [63:0] sti_data_w;
5789wire [7:0] sti_size_m;
5790reg [7:0] sti_size_b;
5791reg [7:0] sti_size_w;
5792wire [7:0] sti_itype_w;
5793reg [7:0] itype_w;
5794wire [63:0] sbd_st_data_b;
5795reg [63:0] sbd_st_data_w;
5796wire flip_size_b;
5797
5798wire atomic_b;
5799wire rmo_st_b;
5800wire blk_inst_b;
5801reg blk_inst_w;
5802
5803wire bst_in_prog_b;
5804reg bst_in_prog_w;
5805wire [39:0] bst_pa_b;
5806reg [39:0] bst_pa_w;
5807wire [2:0] bst_tid_b;
5808reg [2:0] bst_tid_w;
5809wire [39:0] st_pa_b;
5810reg [39:0] st_pa_w;
5811wire [2:0] st_tid_b;
5812reg [2:0] st_tid_w;
5813
5814wire store_inv_e;
5815reg store_inv_m;
5816reg store_inv_b;
5817reg store_inv_w;
5818wire [5:0] stinv_tnum_e;
5819reg [5:0] stinv_tnum_m;
5820reg [5:0] stinv_tnum_b;
5821reg [5:0] stinv_tnum_w;
5822
5823wire store_update_e;
5824reg store_update_m;
5825reg store_update_b;
5826reg store_update_w;
5827wire [2:0] stu_tid_e;
5828reg [2:0] stu_tid_m;
5829reg [2:0] stu_tid_b;
5830reg [2:0] stu_tid_w;
5831wire [5:0] stu_tnum_e;
5832reg [5:0] stu_tnum_m;
5833reg [5:0] stu_tnum_b;
5834reg [5:0] stu_tnum_w;
5835
5836wire [7:0] asi_st_dequeue;
5837wire [7:0] st_ack_no_asi_e;
5838reg [7:0] st_ack_no_asi_m;
5839reg [7:0] st_ack_no_asi_b;
5840wire [7:0] store_ack_b;
5841reg [7:0] store_ack_w;
5842wire [7:0] st_ack_rmo_b;
5843reg [7:0] st_ack_rmo_w;
5844reg sta_rmo;
5845reg [2:0] sta_tid;
5846reg [5:0] sta_tnum;
5847reg sta_suppress [0:7]; // 1 per thread
5848wire st_io_asi;
5849wire [2:0] st_io_tid;
5850wire [7:0] st_data_access_e;
5851reg [7:0] st_data_access_m;
5852reg [7:0] st_data_access_b;
5853reg [7:0] st_data_access_w;
5854reg [2:0] tmp_tid;
5855reg [5:0] tmp_tnum;
5856
5857reg [39:0] store_pa_m;
5858reg [39:0] store_pa_b;
5859reg [39:0] store_pa_w;
5860
5861wire [1:0] l1_way_select;
5862wire [6:0] l1_index;
5863wire [27:0] my_way;
5864wire [27:0] way0;
5865wire [27:0] way1;
5866wire [27:0] way2;
5867wire [27:0] way3;
5868
5869wire [3:0] evict_inv_e;
5870reg [3:0] evict_inv_m;
5871reg [3:0] evict_inv_b;
5872reg [3:0] evict_inv_w;
5873wire [2:0] evict_srcid_e;
5874reg [2:0] evict_srcid_m;
5875reg [2:0] evict_srcid_b;
5876reg [2:0] evict_srcid_w;
5877
5878wire [8:0] pcx_req;
5879reg [8:0] pcx_req_1;
5880wire [129:0] pcx_data;
5881
5882wire perfmon;
5883wire perfmon_g;
5884reg perfmon_m;
5885reg perfmon_b;
5886reg perfmon_w;
5887wire [2:0] perfmon_tid;
5888wire [2:0] perfmon_tid_g;
5889reg [2:0] perfmon_tid_m;
5890reg [2:0] perfmon_tid_b;
5891reg [2:0] perfmon_tid_w;
5892wire [5:0] perfmon_tnum;
5893wire [7:0] perfmon_mask;
5894wire [7:0] perfmon_mask_g;
5895reg [7:0] perfmon_mask_m;
5896reg [7:0] perfmon_mask_b;
5897reg [7:0] perfmon_mask_w;
5898
5899wire [7:0] bst_kill;
5900reg [2:0] bst_kill_tid;
5901reg [5:0] bst_kill_tnum;
5902
5903wire [7:0] stb_state0_m;
5904wire [7:0] stb_state1_m;
5905wire [7:0] stb_state2_m;
5906wire [7:0] stb_state3_m;
5907wire [7:0] stb_state4_m;
5908wire [7:0] stb_state5_m;
5909wire [7:0] stb_state6_m;
5910wire [7:0] stb_state7_m;
5911reg [7:0] stb_state0_b;
5912reg [7:0] stb_state1_b;
5913reg [7:0] stb_state2_b;
5914reg [7:0] stb_state3_b;
5915reg [7:0] stb_state4_b;
5916reg [7:0] stb_state5_b;
5917reg [7:0] stb_state6_b;
5918reg [7:0] stb_state7_b;
5919reg [7:0] stb_state0_w;
5920reg [7:0] stb_state1_w;
5921reg [7:0] stb_state2_w;
5922reg [7:0] stb_state3_w;
5923reg [7:0] stb_state4_w;
5924reg [7:0] stb_state5_w;
5925reg [7:0] stb_state6_w;
5926reg [7:0] stb_state7_w;
5927reg [7:0] stb_state;
5928reg stb_last;
5929
5930// Copy of dtag
5931reg [27:0] dta_way0 [127:0];
5932reg [27:0] dta_way1 [127:0];
5933reg [27:0] dta_way2 [127:0];
5934reg [27:0] dta_way3 [127:0];
5935
5936//---------------------
5937// Misc Signals
5938wire [2:0] mycid;
5939integer tstamp;
5940integer junk;
5941integer i;
5942
5943initial begin // {
5944 ldf_tnum_w = 6'b0;
5945 dsrc = 2'b0;
5946 sta_tid = 3'b0;
5947 sta_tnum = 6'b0;
5948 for (i=0; i<=7; i=i+1) begin
5949 sta_suppress[i] = 1'b0;
5950 end
5951
5952end // }
5953
5954// for debug only - allows display in Debussy
5955wire sta_suppress0;
5956wire sta_suppress1;
5957wire sta_suppress2;
5958wire sta_suppress3;
5959wire sta_suppress4;
5960wire sta_suppress5;
5961wire sta_suppress6;
5962wire sta_suppress7;
5963
5964 assign sta_suppress0 = sta_suppress[0];
5965 assign sta_suppress1 = sta_suppress[1];
5966 assign sta_suppress2 = sta_suppress[2];
5967 assign sta_suppress3 = sta_suppress[3];
5968 assign sta_suppress4 = sta_suppress[4];
5969 assign sta_suppress5 = sta_suppress[5];
5970 assign sta_suppress6 = sta_suppress[6];
5971 assign sta_suppress7 = sta_suppress[7];
5972
5973//----------------------------------------------------------
5974//----------------------------------------------------------
5975// DUT probes
5976
5977 assign mycid = 6;
5978
5979//---------------------
5980// Load Issue
5981
5982 // If Load to IO ASIs, load issue should not be sent.
5983 // In this case, asi_internal_w is asserted and will suppress load_w.
5984
5985 assign load_w = `SPC6.lsu.dcc.ld_inst_vld_w &
5986 ~`PROBES6.asi_internal_w &
5987 ~`SPC6.lsu.dcc.flush_w &
5988 ~ldi_pf_w;
5989
5990 // ldxa to IO ASI are already suppressed since load_w will not assert.
5991 // ldi_suppress is required to also suppress normal ld to IO ASI address range.
5992 assign ldi_suppress = (ldi_pa_w[39:32] == `IO_ASI_ADDR);
5993
5994 assign ldi_tid_w = `SPC6.lsu.dcc.tid_w;
5995 assign ldi_tnum_w = {mycid,ldi_tid_w};
5996 assign ldi_size_b = `SPC6.lsu.dcc.ldst_sz_b; // 2 bits
5997 assign ldi_atomic_b = `SPC6.lsu.dcc.atomic_b;
5998 assign ldi_qld_b = `SPC6.lsu.dcc.quad_ldd_b;
5999 assign ldi_ldbl_b = `SPC6.lsu.dcc_ldbl_b;
6000 assign ldi_ldd_b = ldi_ldbl_b & !ldi_qld_b;
6001 assign ldi_bld_b = `SPC6.lsu.dcc.dcc_blk_inst_b;
6002 assign ldi_pf_b = `SPC6.lsu.dcc.pref_inst_b;
6003
6004 // pa, tid are same for LoadIssue and StoreIssue
6005 assign ldi_pa_b = {`SPC6.lsu.tlb_pgnum[39:13],
6006 `SPC6.lsu.lmd.lsu_va_b[12:0]};
6007
6008//---------------------
6009// Load Fill
6010
6011 assign load_fill_e = `SPC6.lsu.dcc.ld_fill_e;
6012 assign ldf_tid_e = `SPC6.lsu.cid.cid_tid;
6013 assign ldf_pa_e = {`SPC6.lsu.lmd.lmd_fill_addr_e[39:3],3'b0};
6014
6015//---------------------
6016// Store Issue
6017
6018 // blk_inst_w will suppress store_w for 1st of 9 cycles on block store.
6019
6020 // If Store to IO ASIs, store issue should not be sent.
6021 // In this case, asi_internal_w is asserted and will suppress store_w.
6022
6023 assign unflushed_store_w = `SPC6.lsu.sbc.unflushed_store_w;
6024
6025 assign store_w = unflushed_store_w &
6026 (~(`PROBES6.asi_internal_w | blk_inst_w) |
6027 bst_in_prog_w);
6028
6029 assign atomic_b = `SPC6.lsu.dcc.atomic_b;
6030 assign rmo_st_b = `SPC6.lsu.sbc_rmo_st_b;
6031 assign blk_inst_b = `SPC6.lsu.dcc.dcc_blk_inst_b;
6032
6033 assign sti_tnum_w = {mycid,sti_tid_w};
6034 assign sti_size_m = `SPC6.lsu.dcc_ldst_bmask;
6035
6036 // flip_size will assert if endian swap for partial store is needed
6037 assign flip_size_b = `SPC6.lsu.dcc.pst_asi_b & `SPC6.lsu.dcc.tlb_tte_ie_b & `SPC6.lsu.dcc.tlb_tte_vld_b & `SPC6.lsu.dcc.st_inst_vld_b;
6038
6039 // Change itype only when control signals are valid
6040 assign sti_itype_w = unflushed_store_w ? itype_w : sti_itype_w;
6041
6042 // It is correct to mix W & B stage signals for this.
6043 // STD is a 2 cycle instruction.
6044 // inst valid in W, data in B (1 cycle behind)
6045 assign sti_data_w = `SPC6.lsu.sbc.std_inst_w ?
6046 sbd_st_data_b :
6047 sbd_st_data_w;
6048 assign sbd_st_data_b = `SPC6.lsu.sbd_st_data_b;
6049
6050 // Use different pa,tid if block store
6051 assign sti_pa_b = bst_in_prog_b ? bst_pa_b : st_pa_b;
6052 assign sti_tid_b = bst_in_prog_b ? bst_tid_b : st_tid_b;
6053
6054 // stxa to IO ASI are already suppressed since store_w will not assert.
6055 // sti_suppress is required to also suppress normal st to IO ASI address range.
6056 assign sti_suppress = (sti_pa_w[39:32] == `IO_ASI_ADDR);
6057
6058 // Normal Store
6059 assign st_pa_b = {`SPC6.lsu.tlb_pgnum[39:13],
6060 `SPC6.lsu.lmd.lsu_va_b[12:0]};
6061 assign st_tid_b = `SPC6.lsu.dcc.tid_b;
6062
6063 // Block Store
6064 assign bst_in_prog_b = `SPC6.lsu.sbc.bst_in_prog_b;
6065 assign bst_pa_b = {`SPC6.lsu.sbd.st_addr_b[39:3],3'b0};
6066 assign bst_tid_b = `SPC6.lsu.sbc.bst_tid;
6067
6068//---------------------
6069// Store Ack
6070
6071assign asi_st_dequeue[7:0] = `SPC6.lsu.dcc_asi_rtn_vld[7:0] &
6072 {8{~`SPC6.lsu.dcc_asi_rtn_rd}};
6073
6074 assign st_ack_no_asi_e = `SPC6.lsu.cic.cic_st_dequeue[7:0] &
6075 ~asi_st_dequeue[7:0] &
6076 ~`SPC6.lsu.cic.sbc_bst_sel[7:0];
6077
6078 assign st_ack_rmo_b = {`SPC6.lsu.sbs7.rmo_st_commit_p4,
6079 `SPC6.lsu.sbs6.rmo_st_commit_p4,
6080 `SPC6.lsu.sbs5.rmo_st_commit_p4,
6081 `SPC6.lsu.sbs4.rmo_st_commit_p4,
6082 `SPC6.lsu.sbs3.rmo_st_commit_p4,
6083 `SPC6.lsu.sbs2.rmo_st_commit_p4,
6084 `SPC6.lsu.sbs1.rmo_st_commit_p4,
6085 `SPC6.lsu.sbs0.rmo_st_commit_p4
6086 };
6087
6088 // It is possible to see 2 threads store_ack in same cycle
6089 // (1 st_ack_no_asi & 1 st_ack_rmo)
6090
6091 assign store_ack_b = st_ack_no_asi_b | st_ack_rmo_b;
6092
6093 // cic_st_atm_cmplt is atomic store completing (same time as store ack)
6094 // (lsu.lmc.dcl2u_err | dcl2nd_err) indicate a data_access_error condition
6095 assign st_data_access_e = {8{(`SPC6.lsu.cic.cic_st_atm_cmplt &
6096 (`SPC6.lsu.lmc.dcl2u_err | `SPC6.lsu.lmc.dcl2nd_err))}} &
6097 `SPC6.lsu.cic.cic_st_dequeue[7:0];
6098//---------------------
6099// Store Inv
6100
6101 // Same as evict_inv_e but with cpq_evict deasserted
6102 assign store_inv_e = `SPC6.lsu.cic_invalidate_e &
6103 (`SPC6.lsu.cic_inv_wen_e!=0)&
6104 ~`SPC6.lsu.cic.cpq_evict &
6105 ~`SPC6.lsu.cic.cid_set_inval &
6106 ~`SPC6.lsu.cic.cic_xinval_e &
6107 ~(`SPC6.lsu.cic.cid_pkt_type[4:0] == 5'b10110);
6108 assign stinv_tnum_e =
6109 {`SPC6.lsu.cid.cpq_data_out[`CPX_VACK_CID],
6110 `SPC6.lsu.cid.cid_tid};
6111
6112//---------------------
6113// Store Update
6114
6115 assign store_update_e = `SPC6.lsu.cic_st_update_e;
6116 assign stu_tid_e = `SPC6.lsu.cid.cid_tid;
6117 assign stu_tnum_e = {mycid,stu_tid_e};
6118
6119 assign l1_index = {`SPC6.lsu.cid.cpq_data_out[116],
6120 `SPC6.lsu.cid.cpq_data_out[115],
6121 `SPC6.lsu.cid.cpq_data_out[114],
6122 `SPC6.lsu.cid.cpq_data_out[113],
6123 `SPC6.lsu.cid.cpq_data_out[112],
6124 `SPC6.lsu.cid.cpq_data_out[122],
6125 `SPC6.lsu.cid.cpq_data_out[121]
6126 };
6127 assign l1_way_select = `SPC6.lsu.cid_inv_vec[17:16];
6128
6129//---------------------
6130// EvictInv
6131
6132 // Same as store_inv_e but with cpq_evict asserted
6133 // LSU can invalidate 1-4 Dcache lines
6134 assign evict_inv_e[3:0] = {4{`SPC6.lsu.cic_invalidate_e & // enable for 4 bit wen below
6135 (`SPC6.lsu.cic_inv_wen_e!=0)&
6136 `SPC6.lsu.cic.cpq_evict &
6137 ~`SPC6.lsu.cic.cid_set_inval &
6138 ~`SPC6.lsu.cic.cic_xinval_e}} &
6139
6140 {|(`SPC6.lsu.cic.evict_inv_wen[15:12]), // 4 bit field - 1 hot. Send evinv when any one set.
6141 |(`SPC6.lsu.cic.evict_inv_wen[11:8]),
6142 |(`SPC6.lsu.cic.evict_inv_wen[7:4]),
6143 |(`SPC6.lsu.cic.evict_inv_wen[3:0])
6144 };
6145
6146 assign evict_srcid_e = `SPC6.lsu.cid.cpq_data_out[114:112];
6147
6148
6149//---------------------
6150// Detect Store to IO ASI in PCX crossbar packet.
6151// This causes next Store Ack to be suppressed.
6152
6153// Normal Store only since atomics are always to cacheable space
6154
6155// Trigger on Store to crossbar.
6156// If Store request is retried on crossbar (due to no grant),
6157// then, st_io_asi will fire multiple times for the same request.
6158// This is OK because it just causes sta_suppress to be set multiple times.
6159
6160 assign pcx_req = `SPC6.spc_pcx_req_pq;
6161 assign pcx_data = `SPC6.spc_pcx_data_pa;
6162
6163 assign st_io_asi = (pcx_req_1 != 9'b0) &
6164 (pcx_data [`PCX_VALID]==1'b1) &
6165 (pcx_data [`PCX_RQTYP]==`CCX_REQ_ST) &
6166 (pcx_data [103:96]==`IO_ASI_ADDR); // Upper byte of 40 bit addr
6167
6168 assign st_io_tid = pcx_data [`PCX_TID];
6169
6170 assign stb_state0_m = `SPC6.lsu.sbs0.stb_state_vld[7:0];
6171 assign stb_state1_m = `SPC6.lsu.sbs1.stb_state_vld[7:0];
6172 assign stb_state2_m = `SPC6.lsu.sbs2.stb_state_vld[7:0];
6173 assign stb_state3_m = `SPC6.lsu.sbs3.stb_state_vld[7:0];
6174 assign stb_state4_m = `SPC6.lsu.sbs4.stb_state_vld[7:0];
6175 assign stb_state5_m = `SPC6.lsu.sbs5.stb_state_vld[7:0];
6176 assign stb_state6_m = `SPC6.lsu.sbs6.stb_state_vld[7:0];
6177 assign stb_state7_m = `SPC6.lsu.sbs7.stb_state_vld[7:0];
6178
6179//---------------------
6180// Load Data (hit only) (See ldst_l2.v for Load Data - miss)
6181
6182 assign load_data_hit = load_w && (hit_w | fraw_w);
6183 assign ld_miss_b = `SPC6.lsu.dcc.dcc_ld_miss_b;
6184 assign fraw_w = `SPC6.lsu.lmc.ld_raw_bypass_w;
6185 assign hit_w = ~ld_miss_w & ~stb_hit_w;
6186 assign miss_w = ~fraw_w & (ld_miss_w | stb_hit_w);
6187
6188//---------------------
6189// Load Pop
6190
6191 assign perfmon_g = `SPC6.lsu.lsu_perfmon_trap_g;
6192 assign perfmon_tid_g = `SPC6.lsu.lsu_dcerr_tid_g;
6193 // perfmon_mask will not fire if trap is not enabled or higher priority trap is taken.
6194 assign perfmon_mask_g = {`SPC6.tlu.fls1.pil_mask_15[3:0], `SPC6.tlu.fls0.pil_mask_15[3:0]} &
6195 ~{8 {`SPC6.lsu_dcl2u_err_g | `SPC6.lsu_dcl2nd_err_g}};
6196
6197 assign perfmon = perfmon_w;
6198 assign perfmon_tid = perfmon_tid_w;
6199 assign perfmon_tnum = {mycid,perfmon_tid_w};
6200 assign perfmon_mask = perfmon_mask_w;
6201
6202
6203
6204//---------------------
6205// Store Pop
6206
6207 assign bst_kill = {`SPC6.lsu.sbs7.bst_kill,
6208 `SPC6.lsu.sbs6.bst_kill,
6209 `SPC6.lsu.sbs5.bst_kill,
6210 `SPC6.lsu.sbs4.bst_kill,
6211 `SPC6.lsu.sbs3.bst_kill,
6212 `SPC6.lsu.sbs2.bst_kill,
6213 `SPC6.lsu.sbs1.bst_kill,
6214 `SPC6.lsu.sbs0.bst_kill};
6215
6216//----------------------------------------------------------
6217//----------------------------------------------------------
6218
6219always @ (posedge `SPC6.l2clk) begin // {
6220
6221 tstamp = `TOP.core_cycle_cnt - 1;
6222
6223 //------------------------------
6224 // Pipeline from B to W
6225
6226 ldi_pa_w <= ldi_pa_b;
6227 ld_miss_w <= ld_miss_b;
6228 stb_hit_w <= `SPC6.lsu.stb_cam_hit;
6229 ldi_pf_w <= ldi_pf_b;
6230 ldi_size_w <= ldi_size_b;
6231 load_fill_m <= load_fill_e;
6232 load_fill_b <= load_fill_m;
6233 load_fill_w <= load_fill_b;
6234 ldf_tid_m <= ldf_tid_e;
6235 ldf_tid_b <= ldf_tid_m;
6236 ldf_tid_w <= ldf_tid_b;
6237 ldf_pa_m <= ldf_pa_e;
6238 ldf_pa_b <= ldf_pa_m;
6239 ldf_pa_w <= ldf_pa_b;
6240
6241 sti_size_b <= sti_size_m;
6242 sti_size_w <= (flip_size_b) ? {sti_size_b[0],sti_size_b[1],sti_size_b[2],sti_size_b[3],
6243 sti_size_b[4],sti_size_b[5],sti_size_b[6],sti_size_b[7]}
6244 : sti_size_b;
6245 sti_pa_w <= sti_pa_b;
6246 sti_tid_w <= sti_tid_b;
6247 st_ack_no_asi_m <= st_ack_no_asi_e;
6248 st_ack_no_asi_b <= st_ack_no_asi_m;
6249 st_data_access_m <= st_data_access_e;
6250 st_data_access_b <= st_data_access_m;
6251 st_data_access_w <= st_data_access_b;
6252 store_ack_w <= store_ack_b;
6253 store_update_m <= store_update_e;
6254 store_update_b <= store_update_m;
6255 store_update_w <= store_update_b;
6256 store_inv_m <= store_inv_e;
6257 store_inv_b <= store_inv_m;
6258 store_inv_w <= store_inv_b;
6259 stinv_tnum_m <= stinv_tnum_e;
6260 stinv_tnum_b <= stinv_tnum_m;
6261 stinv_tnum_w <= stinv_tnum_b;
6262 st_ack_rmo_w <= st_ack_rmo_b;
6263 stu_tid_m <= stu_tid_e;
6264 stu_tid_b <= stu_tid_m;
6265 stu_tid_w <= stu_tid_b;
6266 stu_tnum_m <= stu_tnum_e;
6267 stu_tnum_b <= stu_tnum_m;
6268 stu_tnum_w <= stu_tnum_b;
6269 store_pa_b <= store_pa_m;
6270 store_pa_w <= store_pa_b;
6271 bst_in_prog_w <= bst_in_prog_b;
6272 blk_inst_w <= blk_inst_b;
6273 sbd_st_data_w <= sbd_st_data_b;
6274 evict_inv_m <= evict_inv_e;
6275 evict_inv_b <= evict_inv_m;
6276 evict_inv_w <= evict_inv_b;
6277 evict_srcid_m <= evict_srcid_e;
6278 evict_srcid_b <= evict_srcid_m;
6279 evict_srcid_w <= evict_srcid_b;
6280 pcx_req_1 <= pcx_req;
6281 stb_state0_b <= stb_state0_m;
6282 stb_state1_b <= stb_state1_m;
6283 stb_state2_b <= stb_state2_m;
6284 stb_state3_b <= stb_state3_m;
6285 stb_state4_b <= stb_state4_m;
6286 stb_state5_b <= stb_state5_m;
6287 stb_state6_b <= stb_state6_m;
6288 stb_state7_b <= stb_state7_m;
6289 stb_state0_w <= stb_state0_b;
6290 stb_state1_w <= stb_state1_b;
6291 stb_state2_w <= stb_state2_b;
6292 stb_state3_w <= stb_state3_b;
6293 stb_state4_w <= stb_state4_b;
6294 stb_state5_w <= stb_state5_b;
6295 stb_state6_w <= stb_state6_b;
6296 stb_state7_w <= stb_state7_b;
6297
6298 perfmon_m <= perfmon_g;
6299 perfmon_b <= perfmon_m;
6300 perfmon_w <= perfmon_b;
6301 perfmon_tid_m <= perfmon_tid_g;
6302 perfmon_tid_b <= perfmon_tid_m;
6303 perfmon_tid_w <= perfmon_tid_b;
6304 perfmon_mask_m <= perfmon_mask_g;
6305 perfmon_mask_b <= perfmon_mask_m;
6306 perfmon_mask_w <= perfmon_mask_b;
6307
6308 //----------------------------------------------------------
6309 // Calculate pa for STUPDATE and STINV
6310 // Moved this into the always block to avoid the constant
6311 // probing of the dtag memory structure.
6312
6313 if (store_inv_e | store_update_e) begin // {
6314 store_pa_m[2:0] <= 3'b000;
6315 store_pa_m[10:3] <= {`SPC6.lsu.cid.cpq_data_out[116],
6316 `SPC6.lsu.cid.cpq_data_out[115],
6317 `SPC6.lsu.cid.cpq_data_out[114],
6318 `SPC6.lsu.cid.cpq_data_out[113],
6319 `SPC6.lsu.cid.cpq_data_out[112],
6320 `SPC6.lsu.cid.cpq_data_out[122],
6321 `SPC6.lsu.cid.cpq_data_out[121],
6322 `SPC6.lsu.cid.cpq_data_out[104]
6323 };
6324 store_pa_m[38:11] <= (l1_way_select==2'h0) ? dta_way0[l1_index] :
6325 (l1_way_select==2'h1) ? dta_way1[l1_index] :
6326 (l1_way_select==2'h2) ? dta_way2[l1_index] : dta_way3[l1_index];
6327 store_pa_m[39] <= 1'b0; // Only memory stores get inv/update
6328 end // }
6329
6330
6331 // After Store to IO ASI is detected at StI time, suppress the next Store Ack
6332 // There is only 1 store to IO ASI active at one time per thread because
6333 // that is all the LSU allows.
6334 if (st_io_asi) begin
6335 sta_suppress [st_io_tid] <= 1'b1;
6336 end
6337
6338 case ({ldi_atomic_b,ldi_bld_b,ldi_ldd_b,ldi_qld_b,ldi_pf_b})
6339 5'b00000: ldi_itype_w <= `ITYPE_LOAD;
6340 5'b00001: ldi_itype_w <= `ITYPE_PREFETCH;
6341 5'b00010: ldi_itype_w <= `ITYPE_QUAD_LOAD;
6342 5'b00100: ldi_itype_w <= `ITYPE_DOUBLE_LOAD;
6343 5'b01000: ldi_itype_w <= `ITYPE_BLOCK_LOAD;
6344 5'b10000: ldi_itype_w <= `ITYPE_ATOMIC;
6345 default: ldi_itype_w <= `ITYPE_NO; // Illegal
6346 endcase
6347
6348 case ({atomic_b,rmo_st_b,bst_in_prog_b})
6349 3'b000: itype_w <= `ITYPE_STORE;
6350 3'b010: itype_w <= `ITYPE_BLK_INIT_ST;
6351 3'b011: itype_w <= `ITYPE_BLOCK_STORE;
6352 3'b100: itype_w <= `ITYPE_ATOMIC;
6353 3'b001,
6354 3'b101,
6355 3'b110,
6356 3'b111: itype_w <= `ITYPE_NO; // Illegal
6357 endcase
6358
6359 //----------------------------------------------------------
6360 //----------------------------------------------------------
6361 // Load Issue
6362
6363 // Load Issue must be before Store Issue for atomic
6364
6365 if (load_w) begin // {
6366
6367 if (ldi_suppress==1'b0) begin // {
6368 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
6369 `PR_INFO ("pli_ldst", `INFO,
6370 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h size=%h typ=%0h ts=%0d",
6371 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
6372 junk = $sim_send(`PLI_MEM_LD_ISSUE,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
6373 end // }
6374 end // }
6375 else begin // {
6376 `PR_INFO ("pli_ldst", `INFO,
6377 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h Suppress for IO ASI",mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w);
6378 end // }
6379
6380 if (`PARGS.show_memop_on) begin // {
6381 `PR_NORMAL ("pli_ldst", `NORMAL,
6382 "C%0d T%0d MEMOP_LOAD tid=%d pa=%h ts=%0d (LSU - W stage)",
6383 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,tstamp);
6384 end // }
6385
6386 end // }
6387
6388 //----------------------------------------------------------
6389 //----------------------------------------------------------
6390 // Load Data (hit only) (See ldst_l2.v for Load Data - miss)
6391
6392 if (load_data_hit) begin // {
6393
6394 dsrc = hit_w ? `DSRC_L1 : `DSRC_STB;
6395
6396 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
6397 `PR_INFO ("pli_ldst", `INFO,
6398 "C%0d T%0d PLI_MEM_LDDATA tid=%d pa=%h dsrc=%0h ts=%0d",
6399 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
6400 junk = $sim_send(`PLI_MEM_LD_DATA,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
6401 end // }
6402
6403 end // }
6404
6405
6406 //----------------------------------------------------------
6407 //----------------------------------------------------------
6408 // Store Ack
6409 //
6410 // Store Ack cmd must be sent before Store Inv, Store Update for NAS
6411 // Store Ack & Store Update will be in the same timestamp
6412
6413 if (store_ack_w != 8'b0) begin // {
6414
6415 for (i=0; i<=7; i=i+1) begin // {
6416 if (store_ack_w[i]) begin // {
6417 sta_tid = i[2:0];
6418 sta_tnum = {mycid,sta_tid};
6419 sta_rmo = st_ack_rmo_w[i];
6420
6421 if (sta_suppress[sta_tid]==1'b0) begin // {
6422 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
6423 `PR_INFO ("pli_ldst", `INFO,
6424 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
6425 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
6426 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
6427 end // }
6428 end // }
6429
6430 else begin // {
6431
6432 // It is possible for 2 Stores it be in flight because of the delay from CPQ push & pop.
6433 // So, make sure Bench is suppressing the correct Store.
6434 case (sta_tid)
6435 3'h0: stb_state=stb_state0_w;
6436 3'h1: stb_state=stb_state1_w;
6437 3'h2: stb_state=stb_state2_w;
6438 3'h3: stb_state=stb_state3_w;
6439 3'h4: stb_state=stb_state4_w;
6440 3'h5: stb_state=stb_state5_w;
6441 3'h6: stb_state=stb_state6_w;
6442 3'h7: stb_state=stb_state7_w;
6443 default:
6444 `PR_ERROR ("pli_ldst", `ERROR,
6445 "C%0d T%0d PLI_MEM_XXX Bench Error. Should never execute case default",mycid,sta_tid);
6446 endcase
6447
6448 // If stb_state has only 1 bit asserted, then suppress the STACK. Otherwise, send the STACK.
6449 case (stb_state) // {
6450 8'b0000_0000: begin
6451 `PR_ERROR ("pli_ldst", `ERROR,
6452 "C%0d T%0d PLI_MEM_XXX Bench Error. stb_state should not be 8'b0",
6453 mycid,sta_tid);
6454 end
6455 8'b0000_0001,
6456 8'b0000_0010,
6457 8'b0000_0100,
6458 8'b0000_1000,
6459 8'b0001_0000,
6460 8'b0010_0000,
6461 8'b0100_0000,
6462 8'b1000_0000: stb_last = 1'b1;
6463 default: stb_last = 1'b0;
6464 endcase // }
6465
6466 if (stb_last==1'b0) begin // {
6467 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
6468 `PR_INFO ("pli_ldst", `INFO,
6469 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
6470 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
6471 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
6472 end // }
6473 end // }
6474 else begin // {
6475 sta_suppress[sta_tid] <= 1'b0;
6476 `PR_INFO ("pli_ldst", `INFO,
6477 "C%0d T%0d PLI_MEM_STACK tid=%d Suppress for IO ASI",mycid,sta_tid,sta_tnum);
6478 end // }
6479 end // }
6480
6481 end // if (store_ack_w[i]) }
6482 end // for }
6483
6484 end // if (store_ack_w) }
6485
6486 //----------------------------------------------------------
6487 //----------------------------------------------------------
6488 // Store Inv
6489
6490 if (store_inv_w) begin // {
6491
6492 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stinv_tnum_w]) begin // {
6493 `PR_INFO ("pli_ldst", `INFO,
6494 "C%0d PLI_MEM_STINV tid=%d pa=%h cid=%h ts=%0d",
6495 mycid,stinv_tnum_w,store_pa_w,mycid,tstamp);
6496 junk = $sim_send(`PLI_MEM_ST_INV,mycid,stinv_tnum_w,store_pa_w,tstamp);
6497 end // }
6498
6499 end // }
6500
6501
6502 //----------------------------------------------------------
6503 //----------------------------------------------------------
6504 // Store Update
6505
6506 if (store_update_w) begin // {
6507
6508 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stu_tnum_w]) begin // {
6509 `PR_INFO ("pli_ldst", `INFO,
6510 "C%0d T%0d PLI_MEM_STUP tid=%d pa=%h ts=%0d",
6511 mycid,stu_tid_w,stu_tnum_w,store_pa_w,tstamp);
6512 junk = $sim_send(`PLI_MEM_ST_UPDATE,stu_tnum_w,store_pa_w,tstamp);
6513 end // }
6514
6515 end // }
6516
6517 //----------------------------------------------------------
6518 //----------------------------------------------------------
6519 // Load Fill
6520
6521 if (load_fill_w) begin // {
6522
6523 ldf_tnum_w = {mycid,ldf_tid_w};
6524
6525 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldf_tnum_w]) begin // {
6526 `PR_INFO ("pli_ldst", `INFO,
6527 "C%0d T%0d PLI_MEM_LDFILL tid=%d pa=%h ts=%0d",
6528 mycid,ldf_tid_w,ldf_tnum_w,ldf_pa_w,tstamp);
6529 junk = $sim_send(`PLI_MEM_LD_FILL,ldf_tnum_w,ldf_pa_w,tstamp);
6530 end // }
6531
6532 end // }
6533
6534 //----------------------------------------------------------
6535 //----------------------------------------------------------
6536 // Store Issue
6537
6538 if (store_w) begin // {
6539
6540 if (sti_suppress==1'b0) begin // {
6541 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sti_tnum_w]) begin // {
6542 `PR_INFO ("pli_ldst", `INFO,
6543 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h data=%h sz=%h typ=%0h ts=%0d",
6544 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
6545 junk = $sim_send(`PLI_MEM_ST_ISSUE,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
6546 end // }
6547
6548 end // }
6549 else begin // {
6550 `PR_INFO ("pli_ldst", `INFO,
6551 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h Suppress for IO ASI",mycid,sti_tid_w,sti_tnum_w,sti_pa_w);
6552 end // }
6553
6554 if (`PARGS.show_memop_on) begin // {
6555 `PR_NORMAL ("pli_ldst", `NORMAL,
6556 "C%0d T%0d MEMOP_STORE tid=%d pa=%h data=%h sz=%h ts=%0d (LSU - W stage)",
6557 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,tstamp);
6558 end // }
6559
6560 end // }
6561
6562 //----------------------------------------------------------
6563 //----------------------------------------------------------
6564 // EvictInv
6565 // Send 1-4 EvictInv messages per cycle - based on how many Dcache lines were invalidated.
6566
6567 for (i=0; i<=3; i=i+1) begin // {
6568 if (evict_inv_w[i]) begin // {
6569
6570 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on) begin // {
6571 `PR_INFO ("pli_ldst", `INFO,
6572 "C%0d PLI_MEM_EVINV cid=%d srcid=%0d ts=%0d",
6573 mycid,mycid,evict_srcid_w,tstamp);
6574 junk = $sim_send(`PLI_MEM_EVICT_INV,mycid,evict_srcid_w,tstamp);
6575 end // }
6576
6577 end // }
6578 end // }
6579
6580 //----------------------------------------------------------
6581 //----------------------------------------------------------
6582 // Load Pop - special case
6583
6584 // This is required in case of a performance monitor trap due to L2 miss.
6585 // In this case, the trap is not indicated until after the Load pkt returns to the LSU.
6586 // ldst_sync has already sent LDISSUE and LDDATA to Riesling. But, the Load is not executed.
6587 // Load Pop tells Riesling to pop the LDISSUE,LDDATA off of its queues.
6588
6589 if (perfmon & perfmon_mask[perfmon_tid]) begin // {
6590
6591 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[perfmon_tnum]) begin // {
6592 `PR_INFO ("pli_ldst", `INFO,
6593 "C%0d T%0d PLI_MEM_LDPOP tid=%d ts=%0d",
6594 mycid,perfmon_tid,perfmon_tnum,tstamp);
6595 junk = $sim_send(`PLI_MEM_LD_POP,perfmon_tnum);
6596 end // }
6597
6598 end // }
6599
6600 //----------------------------------------------------------
6601 //----------------------------------------------------------
6602 // Store Pop - special cases
6603
6604 // This is required in case of a FRF error trap (internal_proc_error) on a Block Store.
6605 // In this case, the trap is not indicated until after the 8 STISSUE has been sent to Riesling.
6606 // But, the Store is not executed.
6607 // Store Pop tells Riesling to pop the 8 STISSUE off of its queues.
6608
6609 if (bst_kill!==8'b0) begin // {
6610
6611 for (i=0;i<=7;i=i+1) begin
6612 if (bst_kill[i]==1'b1) begin
6613 bst_kill_tid = i;
6614 bst_kill_tnum = {mycid,bst_kill_tid};
6615
6616 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[bst_kill_tnum]) begin // {
6617 `PR_INFO ("pli_ldst", `INFO,
6618 "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
6619 mycid,bst_kill_tid,bst_kill_tnum,tstamp);
6620 junk = $sim_send(`PLI_MEM_ST_POP,bst_kill_tnum);
6621 end // }
6622 end
6623 end
6624
6625 end // }
6626
6627 //--------------------
6628 // This is required for data_access_error on atomic. In this case, Riesling only cleans up the Load,
6629 // but doesn't know it is an atomic so Riesling doesn't clean up the store in its buffers.
6630 // The STPOP tells Riesling to clear the newest Store from the buffers.
6631 // It is possible to have older Stores in-flight but not newer Stores in-flight.
6632
6633// if (st_data_access_w != 8'b0) begin // {
6634//
6635// for (i=0; i<=7; i=i+1) begin // {
6636// if (st_data_access_w[i]) begin // {
6637// tmp_tid = i[2:0];
6638// tmp_tnum = {mycid,tmp_tid};
6639//
6640// if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[tmp_tnum]) begin // {
6641// `PR_INFO ("pli_ldst", `INFO,
6642// "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
6643// mycid,tmp_tid,tmp_tnum,tstamp);
6644// junk = $sim_send(`PLI_MEM_ST_POP,tmp_tnum);
6645// end // }
6646// end // } if st_data_access[i]
6647// end // } for
6648// end // } if st_data_access
6649
6650end // always }
6651
6652//----------------------------------------------------------
6653// Need to model the D arrays to get PA's for store updates and invalidates
6654
6655always @ (negedge `SPC6.l2clk) begin // {
6656 if (`SPC6.lsu.dta.wr_way[0])
6657 dta_way0[`SPC6.lsu.dta.index_y[6:0]] <= `SPC6.lsu.dta.wrtag_y[27:0];
6658 if (`SPC6.lsu.dta.wr_way[1])
6659 dta_way1[`SPC6.lsu.dta.index_y[6:0]] <= `SPC6.lsu.dta.wrtag_y[27:0];
6660 if (`SPC6.lsu.dta.wr_way[2])
6661 dta_way2[`SPC6.lsu.dta.index_y[6:0]] <= `SPC6.lsu.dta.wrtag_y[27:0];
6662 if (`SPC6.lsu.dta.wr_way[3])
6663 dta_way3[`SPC6.lsu.dta.index_y[6:0]] <= `SPC6.lsu.dta.wrtag_y[27:0];
6664end // always }
6665
6666//----------------------------------------------------------
6667`endif
6668endmodule
6669
6670`endif
6671`ifdef CORE_7
6672
6673module ldst_lsu_c7 ();
6674`ifndef GATESIM
6675
6676// common defines
6677`include "defines.vh"
6678`include "nas.vh"
6679// PCX/CPX packet defines (see :/verif/env/common/vera/include)
6680`include "ccx.vri"
6681`include "cmp.vri"
6682
6683//---------------------
6684// Load Signals
6685wire load_w;
6686
6687wire ldi_suppress;
6688wire [2:0] ldi_tid_w;
6689wire [5:0] ldi_tnum_w;
6690wire [39:0] ldi_pa_b;
6691reg [39:0] ldi_pa_w;
6692wire [1:0] ldi_size_b;
6693reg [1:0] ldi_size_w;
6694wire ldi_bld_b;
6695wire ldi_qld_b;
6696wire ldi_ldbl_b;
6697wire ldi_ldd_b;
6698wire ldi_atomic_b;
6699wire ldi_pf_b;
6700reg ldi_pf_w;
6701reg [7:0] ldi_itype_w;
6702reg [7:0] dsrc;
6703
6704wire ld_miss_b;
6705reg ld_miss_w;
6706reg stb_hit_w;
6707wire fraw_w;
6708wire hit_w;
6709wire miss_w;
6710wire load_data_hit;
6711
6712wire load_fill_e;
6713reg load_fill_m;
6714reg load_fill_b;
6715reg load_fill_w;
6716wire [2:0] ldf_tid_e;
6717reg [2:0] ldf_tid_m;
6718reg [2:0] ldf_tid_b;
6719reg [2:0] ldf_tid_w;
6720reg [5:0] ldf_tnum_w;
6721wire [39:0] ldf_pa_e;
6722reg [39:0] ldf_pa_m;
6723reg [39:0] ldf_pa_b;
6724reg [39:0] ldf_pa_w;
6725
6726//---------------------
6727// Store Signals
6728wire unflushed_store_w;
6729wire store_w;
6730wire sti_suppress;
6731wire [2:0] sti_tid_b;
6732reg [2:0] sti_tid_w;
6733wire [5:0] sti_tnum_w;
6734wire [39:0] sti_pa_b;
6735reg [39:0] sti_pa_w;
6736wire [63:0] sti_data_w;
6737wire [7:0] sti_size_m;
6738reg [7:0] sti_size_b;
6739reg [7:0] sti_size_w;
6740wire [7:0] sti_itype_w;
6741reg [7:0] itype_w;
6742wire [63:0] sbd_st_data_b;
6743reg [63:0] sbd_st_data_w;
6744wire flip_size_b;
6745
6746wire atomic_b;
6747wire rmo_st_b;
6748wire blk_inst_b;
6749reg blk_inst_w;
6750
6751wire bst_in_prog_b;
6752reg bst_in_prog_w;
6753wire [39:0] bst_pa_b;
6754reg [39:0] bst_pa_w;
6755wire [2:0] bst_tid_b;
6756reg [2:0] bst_tid_w;
6757wire [39:0] st_pa_b;
6758reg [39:0] st_pa_w;
6759wire [2:0] st_tid_b;
6760reg [2:0] st_tid_w;
6761
6762wire store_inv_e;
6763reg store_inv_m;
6764reg store_inv_b;
6765reg store_inv_w;
6766wire [5:0] stinv_tnum_e;
6767reg [5:0] stinv_tnum_m;
6768reg [5:0] stinv_tnum_b;
6769reg [5:0] stinv_tnum_w;
6770
6771wire store_update_e;
6772reg store_update_m;
6773reg store_update_b;
6774reg store_update_w;
6775wire [2:0] stu_tid_e;
6776reg [2:0] stu_tid_m;
6777reg [2:0] stu_tid_b;
6778reg [2:0] stu_tid_w;
6779wire [5:0] stu_tnum_e;
6780reg [5:0] stu_tnum_m;
6781reg [5:0] stu_tnum_b;
6782reg [5:0] stu_tnum_w;
6783
6784wire [7:0] asi_st_dequeue;
6785wire [7:0] st_ack_no_asi_e;
6786reg [7:0] st_ack_no_asi_m;
6787reg [7:0] st_ack_no_asi_b;
6788wire [7:0] store_ack_b;
6789reg [7:0] store_ack_w;
6790wire [7:0] st_ack_rmo_b;
6791reg [7:0] st_ack_rmo_w;
6792reg sta_rmo;
6793reg [2:0] sta_tid;
6794reg [5:0] sta_tnum;
6795reg sta_suppress [0:7]; // 1 per thread
6796wire st_io_asi;
6797wire [2:0] st_io_tid;
6798wire [7:0] st_data_access_e;
6799reg [7:0] st_data_access_m;
6800reg [7:0] st_data_access_b;
6801reg [7:0] st_data_access_w;
6802reg [2:0] tmp_tid;
6803reg [5:0] tmp_tnum;
6804
6805reg [39:0] store_pa_m;
6806reg [39:0] store_pa_b;
6807reg [39:0] store_pa_w;
6808
6809wire [1:0] l1_way_select;
6810wire [6:0] l1_index;
6811wire [27:0] my_way;
6812wire [27:0] way0;
6813wire [27:0] way1;
6814wire [27:0] way2;
6815wire [27:0] way3;
6816
6817wire [3:0] evict_inv_e;
6818reg [3:0] evict_inv_m;
6819reg [3:0] evict_inv_b;
6820reg [3:0] evict_inv_w;
6821wire [2:0] evict_srcid_e;
6822reg [2:0] evict_srcid_m;
6823reg [2:0] evict_srcid_b;
6824reg [2:0] evict_srcid_w;
6825
6826wire [8:0] pcx_req;
6827reg [8:0] pcx_req_1;
6828wire [129:0] pcx_data;
6829
6830wire perfmon;
6831wire perfmon_g;
6832reg perfmon_m;
6833reg perfmon_b;
6834reg perfmon_w;
6835wire [2:0] perfmon_tid;
6836wire [2:0] perfmon_tid_g;
6837reg [2:0] perfmon_tid_m;
6838reg [2:0] perfmon_tid_b;
6839reg [2:0] perfmon_tid_w;
6840wire [5:0] perfmon_tnum;
6841wire [7:0] perfmon_mask;
6842wire [7:0] perfmon_mask_g;
6843reg [7:0] perfmon_mask_m;
6844reg [7:0] perfmon_mask_b;
6845reg [7:0] perfmon_mask_w;
6846
6847wire [7:0] bst_kill;
6848reg [2:0] bst_kill_tid;
6849reg [5:0] bst_kill_tnum;
6850
6851wire [7:0] stb_state0_m;
6852wire [7:0] stb_state1_m;
6853wire [7:0] stb_state2_m;
6854wire [7:0] stb_state3_m;
6855wire [7:0] stb_state4_m;
6856wire [7:0] stb_state5_m;
6857wire [7:0] stb_state6_m;
6858wire [7:0] stb_state7_m;
6859reg [7:0] stb_state0_b;
6860reg [7:0] stb_state1_b;
6861reg [7:0] stb_state2_b;
6862reg [7:0] stb_state3_b;
6863reg [7:0] stb_state4_b;
6864reg [7:0] stb_state5_b;
6865reg [7:0] stb_state6_b;
6866reg [7:0] stb_state7_b;
6867reg [7:0] stb_state0_w;
6868reg [7:0] stb_state1_w;
6869reg [7:0] stb_state2_w;
6870reg [7:0] stb_state3_w;
6871reg [7:0] stb_state4_w;
6872reg [7:0] stb_state5_w;
6873reg [7:0] stb_state6_w;
6874reg [7:0] stb_state7_w;
6875reg [7:0] stb_state;
6876reg stb_last;
6877
6878// Copy of dtag
6879reg [27:0] dta_way0 [127:0];
6880reg [27:0] dta_way1 [127:0];
6881reg [27:0] dta_way2 [127:0];
6882reg [27:0] dta_way3 [127:0];
6883
6884//---------------------
6885// Misc Signals
6886wire [2:0] mycid;
6887integer tstamp;
6888integer junk;
6889integer i;
6890
6891initial begin // {
6892 ldf_tnum_w = 6'b0;
6893 dsrc = 2'b0;
6894 sta_tid = 3'b0;
6895 sta_tnum = 6'b0;
6896 for (i=0; i<=7; i=i+1) begin
6897 sta_suppress[i] = 1'b0;
6898 end
6899
6900end // }
6901
6902// for debug only - allows display in Debussy
6903wire sta_suppress0;
6904wire sta_suppress1;
6905wire sta_suppress2;
6906wire sta_suppress3;
6907wire sta_suppress4;
6908wire sta_suppress5;
6909wire sta_suppress6;
6910wire sta_suppress7;
6911
6912 assign sta_suppress0 = sta_suppress[0];
6913 assign sta_suppress1 = sta_suppress[1];
6914 assign sta_suppress2 = sta_suppress[2];
6915 assign sta_suppress3 = sta_suppress[3];
6916 assign sta_suppress4 = sta_suppress[4];
6917 assign sta_suppress5 = sta_suppress[5];
6918 assign sta_suppress6 = sta_suppress[6];
6919 assign sta_suppress7 = sta_suppress[7];
6920
6921//----------------------------------------------------------
6922//----------------------------------------------------------
6923// DUT probes
6924
6925 assign mycid = 7;
6926
6927//---------------------
6928// Load Issue
6929
6930 // If Load to IO ASIs, load issue should not be sent.
6931 // In this case, asi_internal_w is asserted and will suppress load_w.
6932
6933 assign load_w = `SPC7.lsu.dcc.ld_inst_vld_w &
6934 ~`PROBES7.asi_internal_w &
6935 ~`SPC7.lsu.dcc.flush_w &
6936 ~ldi_pf_w;
6937
6938 // ldxa to IO ASI are already suppressed since load_w will not assert.
6939 // ldi_suppress is required to also suppress normal ld to IO ASI address range.
6940 assign ldi_suppress = (ldi_pa_w[39:32] == `IO_ASI_ADDR);
6941
6942 assign ldi_tid_w = `SPC7.lsu.dcc.tid_w;
6943 assign ldi_tnum_w = {mycid,ldi_tid_w};
6944 assign ldi_size_b = `SPC7.lsu.dcc.ldst_sz_b; // 2 bits
6945 assign ldi_atomic_b = `SPC7.lsu.dcc.atomic_b;
6946 assign ldi_qld_b = `SPC7.lsu.dcc.quad_ldd_b;
6947 assign ldi_ldbl_b = `SPC7.lsu.dcc_ldbl_b;
6948 assign ldi_ldd_b = ldi_ldbl_b & !ldi_qld_b;
6949 assign ldi_bld_b = `SPC7.lsu.dcc.dcc_blk_inst_b;
6950 assign ldi_pf_b = `SPC7.lsu.dcc.pref_inst_b;
6951
6952 // pa, tid are same for LoadIssue and StoreIssue
6953 assign ldi_pa_b = {`SPC7.lsu.tlb_pgnum[39:13],
6954 `SPC7.lsu.lmd.lsu_va_b[12:0]};
6955
6956//---------------------
6957// Load Fill
6958
6959 assign load_fill_e = `SPC7.lsu.dcc.ld_fill_e;
6960 assign ldf_tid_e = `SPC7.lsu.cid.cid_tid;
6961 assign ldf_pa_e = {`SPC7.lsu.lmd.lmd_fill_addr_e[39:3],3'b0};
6962
6963//---------------------
6964// Store Issue
6965
6966 // blk_inst_w will suppress store_w for 1st of 9 cycles on block store.
6967
6968 // If Store to IO ASIs, store issue should not be sent.
6969 // In this case, asi_internal_w is asserted and will suppress store_w.
6970
6971 assign unflushed_store_w = `SPC7.lsu.sbc.unflushed_store_w;
6972
6973 assign store_w = unflushed_store_w &
6974 (~(`PROBES7.asi_internal_w | blk_inst_w) |
6975 bst_in_prog_w);
6976
6977 assign atomic_b = `SPC7.lsu.dcc.atomic_b;
6978 assign rmo_st_b = `SPC7.lsu.sbc_rmo_st_b;
6979 assign blk_inst_b = `SPC7.lsu.dcc.dcc_blk_inst_b;
6980
6981 assign sti_tnum_w = {mycid,sti_tid_w};
6982 assign sti_size_m = `SPC7.lsu.dcc_ldst_bmask;
6983
6984 // flip_size will assert if endian swap for partial store is needed
6985 assign flip_size_b = `SPC7.lsu.dcc.pst_asi_b & `SPC7.lsu.dcc.tlb_tte_ie_b & `SPC7.lsu.dcc.tlb_tte_vld_b & `SPC7.lsu.dcc.st_inst_vld_b;
6986
6987 // Change itype only when control signals are valid
6988 assign sti_itype_w = unflushed_store_w ? itype_w : sti_itype_w;
6989
6990 // It is correct to mix W & B stage signals for this.
6991 // STD is a 2 cycle instruction.
6992 // inst valid in W, data in B (1 cycle behind)
6993 assign sti_data_w = `SPC7.lsu.sbc.std_inst_w ?
6994 sbd_st_data_b :
6995 sbd_st_data_w;
6996 assign sbd_st_data_b = `SPC7.lsu.sbd_st_data_b;
6997
6998 // Use different pa,tid if block store
6999 assign sti_pa_b = bst_in_prog_b ? bst_pa_b : st_pa_b;
7000 assign sti_tid_b = bst_in_prog_b ? bst_tid_b : st_tid_b;
7001
7002 // stxa to IO ASI are already suppressed since store_w will not assert.
7003 // sti_suppress is required to also suppress normal st to IO ASI address range.
7004 assign sti_suppress = (sti_pa_w[39:32] == `IO_ASI_ADDR);
7005
7006 // Normal Store
7007 assign st_pa_b = {`SPC7.lsu.tlb_pgnum[39:13],
7008 `SPC7.lsu.lmd.lsu_va_b[12:0]};
7009 assign st_tid_b = `SPC7.lsu.dcc.tid_b;
7010
7011 // Block Store
7012 assign bst_in_prog_b = `SPC7.lsu.sbc.bst_in_prog_b;
7013 assign bst_pa_b = {`SPC7.lsu.sbd.st_addr_b[39:3],3'b0};
7014 assign bst_tid_b = `SPC7.lsu.sbc.bst_tid;
7015
7016//---------------------
7017// Store Ack
7018
7019assign asi_st_dequeue[7:0] = `SPC7.lsu.dcc_asi_rtn_vld[7:0] &
7020 {8{~`SPC7.lsu.dcc_asi_rtn_rd}};
7021
7022 assign st_ack_no_asi_e = `SPC7.lsu.cic.cic_st_dequeue[7:0] &
7023 ~asi_st_dequeue[7:0] &
7024 ~`SPC7.lsu.cic.sbc_bst_sel[7:0];
7025
7026 assign st_ack_rmo_b = {`SPC7.lsu.sbs7.rmo_st_commit_p4,
7027 `SPC7.lsu.sbs6.rmo_st_commit_p4,
7028 `SPC7.lsu.sbs5.rmo_st_commit_p4,
7029 `SPC7.lsu.sbs4.rmo_st_commit_p4,
7030 `SPC7.lsu.sbs3.rmo_st_commit_p4,
7031 `SPC7.lsu.sbs2.rmo_st_commit_p4,
7032 `SPC7.lsu.sbs1.rmo_st_commit_p4,
7033 `SPC7.lsu.sbs0.rmo_st_commit_p4
7034 };
7035
7036 // It is possible to see 2 threads store_ack in same cycle
7037 // (1 st_ack_no_asi & 1 st_ack_rmo)
7038
7039 assign store_ack_b = st_ack_no_asi_b | st_ack_rmo_b;
7040
7041 // cic_st_atm_cmplt is atomic store completing (same time as store ack)
7042 // (lsu.lmc.dcl2u_err | dcl2nd_err) indicate a data_access_error condition
7043 assign st_data_access_e = {8{(`SPC7.lsu.cic.cic_st_atm_cmplt &
7044 (`SPC7.lsu.lmc.dcl2u_err | `SPC7.lsu.lmc.dcl2nd_err))}} &
7045 `SPC7.lsu.cic.cic_st_dequeue[7:0];
7046//---------------------
7047// Store Inv
7048
7049 // Same as evict_inv_e but with cpq_evict deasserted
7050 assign store_inv_e = `SPC7.lsu.cic_invalidate_e &
7051 (`SPC7.lsu.cic_inv_wen_e!=0)&
7052 ~`SPC7.lsu.cic.cpq_evict &
7053 ~`SPC7.lsu.cic.cid_set_inval &
7054 ~`SPC7.lsu.cic.cic_xinval_e &
7055 ~(`SPC7.lsu.cic.cid_pkt_type[4:0] == 5'b10110);
7056 assign stinv_tnum_e =
7057 {`SPC7.lsu.cid.cpq_data_out[`CPX_VACK_CID],
7058 `SPC7.lsu.cid.cid_tid};
7059
7060//---------------------
7061// Store Update
7062
7063 assign store_update_e = `SPC7.lsu.cic_st_update_e;
7064 assign stu_tid_e = `SPC7.lsu.cid.cid_tid;
7065 assign stu_tnum_e = {mycid,stu_tid_e};
7066
7067 assign l1_index = {`SPC7.lsu.cid.cpq_data_out[116],
7068 `SPC7.lsu.cid.cpq_data_out[115],
7069 `SPC7.lsu.cid.cpq_data_out[114],
7070 `SPC7.lsu.cid.cpq_data_out[113],
7071 `SPC7.lsu.cid.cpq_data_out[112],
7072 `SPC7.lsu.cid.cpq_data_out[122],
7073 `SPC7.lsu.cid.cpq_data_out[121]
7074 };
7075 assign l1_way_select = `SPC7.lsu.cid_inv_vec[17:16];
7076
7077//---------------------
7078// EvictInv
7079
7080 // Same as store_inv_e but with cpq_evict asserted
7081 // LSU can invalidate 1-4 Dcache lines
7082 assign evict_inv_e[3:0] = {4{`SPC7.lsu.cic_invalidate_e & // enable for 4 bit wen below
7083 (`SPC7.lsu.cic_inv_wen_e!=0)&
7084 `SPC7.lsu.cic.cpq_evict &
7085 ~`SPC7.lsu.cic.cid_set_inval &
7086 ~`SPC7.lsu.cic.cic_xinval_e}} &
7087
7088 {|(`SPC7.lsu.cic.evict_inv_wen[15:12]), // 4 bit field - 1 hot. Send evinv when any one set.
7089 |(`SPC7.lsu.cic.evict_inv_wen[11:8]),
7090 |(`SPC7.lsu.cic.evict_inv_wen[7:4]),
7091 |(`SPC7.lsu.cic.evict_inv_wen[3:0])
7092 };
7093
7094 assign evict_srcid_e = `SPC7.lsu.cid.cpq_data_out[114:112];
7095
7096
7097//---------------------
7098// Detect Store to IO ASI in PCX crossbar packet.
7099// This causes next Store Ack to be suppressed.
7100
7101// Normal Store only since atomics are always to cacheable space
7102
7103// Trigger on Store to crossbar.
7104// If Store request is retried on crossbar (due to no grant),
7105// then, st_io_asi will fire multiple times for the same request.
7106// This is OK because it just causes sta_suppress to be set multiple times.
7107
7108 assign pcx_req = `SPC7.spc_pcx_req_pq;
7109 assign pcx_data = `SPC7.spc_pcx_data_pa;
7110
7111 assign st_io_asi = (pcx_req_1 != 9'b0) &
7112 (pcx_data [`PCX_VALID]==1'b1) &
7113 (pcx_data [`PCX_RQTYP]==`CCX_REQ_ST) &
7114 (pcx_data [103:96]==`IO_ASI_ADDR); // Upper byte of 40 bit addr
7115
7116 assign st_io_tid = pcx_data [`PCX_TID];
7117
7118 assign stb_state0_m = `SPC7.lsu.sbs0.stb_state_vld[7:0];
7119 assign stb_state1_m = `SPC7.lsu.sbs1.stb_state_vld[7:0];
7120 assign stb_state2_m = `SPC7.lsu.sbs2.stb_state_vld[7:0];
7121 assign stb_state3_m = `SPC7.lsu.sbs3.stb_state_vld[7:0];
7122 assign stb_state4_m = `SPC7.lsu.sbs4.stb_state_vld[7:0];
7123 assign stb_state5_m = `SPC7.lsu.sbs5.stb_state_vld[7:0];
7124 assign stb_state6_m = `SPC7.lsu.sbs6.stb_state_vld[7:0];
7125 assign stb_state7_m = `SPC7.lsu.sbs7.stb_state_vld[7:0];
7126
7127//---------------------
7128// Load Data (hit only) (See ldst_l2.v for Load Data - miss)
7129
7130 assign load_data_hit = load_w && (hit_w | fraw_w);
7131 assign ld_miss_b = `SPC7.lsu.dcc.dcc_ld_miss_b;
7132 assign fraw_w = `SPC7.lsu.lmc.ld_raw_bypass_w;
7133 assign hit_w = ~ld_miss_w & ~stb_hit_w;
7134 assign miss_w = ~fraw_w & (ld_miss_w | stb_hit_w);
7135
7136//---------------------
7137// Load Pop
7138
7139 assign perfmon_g = `SPC7.lsu.lsu_perfmon_trap_g;
7140 assign perfmon_tid_g = `SPC7.lsu.lsu_dcerr_tid_g;
7141 // perfmon_mask will not fire if trap is not enabled or higher priority trap is taken.
7142 assign perfmon_mask_g = {`SPC7.tlu.fls1.pil_mask_15[3:0], `SPC7.tlu.fls0.pil_mask_15[3:0]} &
7143 ~{8 {`SPC7.lsu_dcl2u_err_g | `SPC7.lsu_dcl2nd_err_g}};
7144
7145 assign perfmon = perfmon_w;
7146 assign perfmon_tid = perfmon_tid_w;
7147 assign perfmon_tnum = {mycid,perfmon_tid_w};
7148 assign perfmon_mask = perfmon_mask_w;
7149
7150
7151
7152//---------------------
7153// Store Pop
7154
7155 assign bst_kill = {`SPC7.lsu.sbs7.bst_kill,
7156 `SPC7.lsu.sbs6.bst_kill,
7157 `SPC7.lsu.sbs5.bst_kill,
7158 `SPC7.lsu.sbs4.bst_kill,
7159 `SPC7.lsu.sbs3.bst_kill,
7160 `SPC7.lsu.sbs2.bst_kill,
7161 `SPC7.lsu.sbs1.bst_kill,
7162 `SPC7.lsu.sbs0.bst_kill};
7163
7164//----------------------------------------------------------
7165//----------------------------------------------------------
7166
7167always @ (posedge `SPC7.l2clk) begin // {
7168
7169 tstamp = `TOP.core_cycle_cnt - 1;
7170
7171 //------------------------------
7172 // Pipeline from B to W
7173
7174 ldi_pa_w <= ldi_pa_b;
7175 ld_miss_w <= ld_miss_b;
7176 stb_hit_w <= `SPC7.lsu.stb_cam_hit;
7177 ldi_pf_w <= ldi_pf_b;
7178 ldi_size_w <= ldi_size_b;
7179 load_fill_m <= load_fill_e;
7180 load_fill_b <= load_fill_m;
7181 load_fill_w <= load_fill_b;
7182 ldf_tid_m <= ldf_tid_e;
7183 ldf_tid_b <= ldf_tid_m;
7184 ldf_tid_w <= ldf_tid_b;
7185 ldf_pa_m <= ldf_pa_e;
7186 ldf_pa_b <= ldf_pa_m;
7187 ldf_pa_w <= ldf_pa_b;
7188
7189 sti_size_b <= sti_size_m;
7190 sti_size_w <= (flip_size_b) ? {sti_size_b[0],sti_size_b[1],sti_size_b[2],sti_size_b[3],
7191 sti_size_b[4],sti_size_b[5],sti_size_b[6],sti_size_b[7]}
7192 : sti_size_b;
7193 sti_pa_w <= sti_pa_b;
7194 sti_tid_w <= sti_tid_b;
7195 st_ack_no_asi_m <= st_ack_no_asi_e;
7196 st_ack_no_asi_b <= st_ack_no_asi_m;
7197 st_data_access_m <= st_data_access_e;
7198 st_data_access_b <= st_data_access_m;
7199 st_data_access_w <= st_data_access_b;
7200 store_ack_w <= store_ack_b;
7201 store_update_m <= store_update_e;
7202 store_update_b <= store_update_m;
7203 store_update_w <= store_update_b;
7204 store_inv_m <= store_inv_e;
7205 store_inv_b <= store_inv_m;
7206 store_inv_w <= store_inv_b;
7207 stinv_tnum_m <= stinv_tnum_e;
7208 stinv_tnum_b <= stinv_tnum_m;
7209 stinv_tnum_w <= stinv_tnum_b;
7210 st_ack_rmo_w <= st_ack_rmo_b;
7211 stu_tid_m <= stu_tid_e;
7212 stu_tid_b <= stu_tid_m;
7213 stu_tid_w <= stu_tid_b;
7214 stu_tnum_m <= stu_tnum_e;
7215 stu_tnum_b <= stu_tnum_m;
7216 stu_tnum_w <= stu_tnum_b;
7217 store_pa_b <= store_pa_m;
7218 store_pa_w <= store_pa_b;
7219 bst_in_prog_w <= bst_in_prog_b;
7220 blk_inst_w <= blk_inst_b;
7221 sbd_st_data_w <= sbd_st_data_b;
7222 evict_inv_m <= evict_inv_e;
7223 evict_inv_b <= evict_inv_m;
7224 evict_inv_w <= evict_inv_b;
7225 evict_srcid_m <= evict_srcid_e;
7226 evict_srcid_b <= evict_srcid_m;
7227 evict_srcid_w <= evict_srcid_b;
7228 pcx_req_1 <= pcx_req;
7229 stb_state0_b <= stb_state0_m;
7230 stb_state1_b <= stb_state1_m;
7231 stb_state2_b <= stb_state2_m;
7232 stb_state3_b <= stb_state3_m;
7233 stb_state4_b <= stb_state4_m;
7234 stb_state5_b <= stb_state5_m;
7235 stb_state6_b <= stb_state6_m;
7236 stb_state7_b <= stb_state7_m;
7237 stb_state0_w <= stb_state0_b;
7238 stb_state1_w <= stb_state1_b;
7239 stb_state2_w <= stb_state2_b;
7240 stb_state3_w <= stb_state3_b;
7241 stb_state4_w <= stb_state4_b;
7242 stb_state5_w <= stb_state5_b;
7243 stb_state6_w <= stb_state6_b;
7244 stb_state7_w <= stb_state7_b;
7245
7246 perfmon_m <= perfmon_g;
7247 perfmon_b <= perfmon_m;
7248 perfmon_w <= perfmon_b;
7249 perfmon_tid_m <= perfmon_tid_g;
7250 perfmon_tid_b <= perfmon_tid_m;
7251 perfmon_tid_w <= perfmon_tid_b;
7252 perfmon_mask_m <= perfmon_mask_g;
7253 perfmon_mask_b <= perfmon_mask_m;
7254 perfmon_mask_w <= perfmon_mask_b;
7255
7256 //----------------------------------------------------------
7257 // Calculate pa for STUPDATE and STINV
7258 // Moved this into the always block to avoid the constant
7259 // probing of the dtag memory structure.
7260
7261 if (store_inv_e | store_update_e) begin // {
7262 store_pa_m[2:0] <= 3'b000;
7263 store_pa_m[10:3] <= {`SPC7.lsu.cid.cpq_data_out[116],
7264 `SPC7.lsu.cid.cpq_data_out[115],
7265 `SPC7.lsu.cid.cpq_data_out[114],
7266 `SPC7.lsu.cid.cpq_data_out[113],
7267 `SPC7.lsu.cid.cpq_data_out[112],
7268 `SPC7.lsu.cid.cpq_data_out[122],
7269 `SPC7.lsu.cid.cpq_data_out[121],
7270 `SPC7.lsu.cid.cpq_data_out[104]
7271 };
7272 store_pa_m[38:11] <= (l1_way_select==2'h0) ? dta_way0[l1_index] :
7273 (l1_way_select==2'h1) ? dta_way1[l1_index] :
7274 (l1_way_select==2'h2) ? dta_way2[l1_index] : dta_way3[l1_index];
7275 store_pa_m[39] <= 1'b0; // Only memory stores get inv/update
7276 end // }
7277
7278
7279 // After Store to IO ASI is detected at StI time, suppress the next Store Ack
7280 // There is only 1 store to IO ASI active at one time per thread because
7281 // that is all the LSU allows.
7282 if (st_io_asi) begin
7283 sta_suppress [st_io_tid] <= 1'b1;
7284 end
7285
7286 case ({ldi_atomic_b,ldi_bld_b,ldi_ldd_b,ldi_qld_b,ldi_pf_b})
7287 5'b00000: ldi_itype_w <= `ITYPE_LOAD;
7288 5'b00001: ldi_itype_w <= `ITYPE_PREFETCH;
7289 5'b00010: ldi_itype_w <= `ITYPE_QUAD_LOAD;
7290 5'b00100: ldi_itype_w <= `ITYPE_DOUBLE_LOAD;
7291 5'b01000: ldi_itype_w <= `ITYPE_BLOCK_LOAD;
7292 5'b10000: ldi_itype_w <= `ITYPE_ATOMIC;
7293 default: ldi_itype_w <= `ITYPE_NO; // Illegal
7294 endcase
7295
7296 case ({atomic_b,rmo_st_b,bst_in_prog_b})
7297 3'b000: itype_w <= `ITYPE_STORE;
7298 3'b010: itype_w <= `ITYPE_BLK_INIT_ST;
7299 3'b011: itype_w <= `ITYPE_BLOCK_STORE;
7300 3'b100: itype_w <= `ITYPE_ATOMIC;
7301 3'b001,
7302 3'b101,
7303 3'b110,
7304 3'b111: itype_w <= `ITYPE_NO; // Illegal
7305 endcase
7306
7307 //----------------------------------------------------------
7308 //----------------------------------------------------------
7309 // Load Issue
7310
7311 // Load Issue must be before Store Issue for atomic
7312
7313 if (load_w) begin // {
7314
7315 if (ldi_suppress==1'b0) begin // {
7316 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
7317 `PR_INFO ("pli_ldst", `INFO,
7318 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h size=%h typ=%0h ts=%0d",
7319 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
7320 junk = $sim_send(`PLI_MEM_LD_ISSUE,ldi_tnum_w,ldi_pa_w,ldi_size_w,ldi_itype_w,tstamp);
7321 end // }
7322 end // }
7323 else begin // {
7324 `PR_INFO ("pli_ldst", `INFO,
7325 "C%0d T%0d PLI_MEM_LDISSU tid=%d pa=%h Suppress for IO ASI",mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w);
7326 end // }
7327
7328 if (`PARGS.show_memop_on) begin // {
7329 `PR_NORMAL ("pli_ldst", `NORMAL,
7330 "C%0d T%0d MEMOP_LOAD tid=%d pa=%h ts=%0d (LSU - W stage)",
7331 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,tstamp);
7332 end // }
7333
7334 end // }
7335
7336 //----------------------------------------------------------
7337 //----------------------------------------------------------
7338 // Load Data (hit only) (See ldst_l2.v for Load Data - miss)
7339
7340 if (load_data_hit) begin // {
7341
7342 dsrc = hit_w ? `DSRC_L1 : `DSRC_STB;
7343
7344 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldi_tnum_w]) begin // {
7345 `PR_INFO ("pli_ldst", `INFO,
7346 "C%0d T%0d PLI_MEM_LDDATA tid=%d pa=%h dsrc=%0h ts=%0d",
7347 mycid,ldi_tid_w,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
7348 junk = $sim_send(`PLI_MEM_LD_DATA,ldi_tnum_w,ldi_pa_w,dsrc,tstamp);
7349 end // }
7350
7351 end // }
7352
7353
7354 //----------------------------------------------------------
7355 //----------------------------------------------------------
7356 // Store Ack
7357 //
7358 // Store Ack cmd must be sent before Store Inv, Store Update for NAS
7359 // Store Ack & Store Update will be in the same timestamp
7360
7361 if (store_ack_w != 8'b0) begin // {
7362
7363 for (i=0; i<=7; i=i+1) begin // {
7364 if (store_ack_w[i]) begin // {
7365 sta_tid = i[2:0];
7366 sta_tnum = {mycid,sta_tid};
7367 sta_rmo = st_ack_rmo_w[i];
7368
7369 if (sta_suppress[sta_tid]==1'b0) begin // {
7370 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
7371 `PR_INFO ("pli_ldst", `INFO,
7372 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
7373 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
7374 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
7375 end // }
7376 end // }
7377
7378 else begin // {
7379
7380 // It is possible for 2 Stores it be in flight because of the delay from CPQ push & pop.
7381 // So, make sure Bench is suppressing the correct Store.
7382 case (sta_tid)
7383 3'h0: stb_state=stb_state0_w;
7384 3'h1: stb_state=stb_state1_w;
7385 3'h2: stb_state=stb_state2_w;
7386 3'h3: stb_state=stb_state3_w;
7387 3'h4: stb_state=stb_state4_w;
7388 3'h5: stb_state=stb_state5_w;
7389 3'h6: stb_state=stb_state6_w;
7390 3'h7: stb_state=stb_state7_w;
7391 default:
7392 `PR_ERROR ("pli_ldst", `ERROR,
7393 "C%0d T%0d PLI_MEM_XXX Bench Error. Should never execute case default",mycid,sta_tid);
7394 endcase
7395
7396 // If stb_state has only 1 bit asserted, then suppress the STACK. Otherwise, send the STACK.
7397 case (stb_state) // {
7398 8'b0000_0000: begin
7399 `PR_ERROR ("pli_ldst", `ERROR,
7400 "C%0d T%0d PLI_MEM_XXX Bench Error. stb_state should not be 8'b0",
7401 mycid,sta_tid);
7402 end
7403 8'b0000_0001,
7404 8'b0000_0010,
7405 8'b0000_0100,
7406 8'b0000_1000,
7407 8'b0001_0000,
7408 8'b0010_0000,
7409 8'b0100_0000,
7410 8'b1000_0000: stb_last = 1'b1;
7411 default: stb_last = 1'b0;
7412 endcase // }
7413
7414 if (stb_last==1'b0) begin // {
7415 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sta_tnum]) begin // {
7416 `PR_INFO ("pli_ldst", `INFO,
7417 "C%0d T%0d PLI_MEM_STACK tid=%d rmo=%0h ts=%0d",
7418 mycid,sta_tid,sta_tnum,sta_rmo,tstamp);
7419 junk = $sim_send(`PLI_MEM_ST_ACK,sta_tnum,sta_rmo,tstamp);
7420 end // }
7421 end // }
7422 else begin // {
7423 sta_suppress[sta_tid] <= 1'b0;
7424 `PR_INFO ("pli_ldst", `INFO,
7425 "C%0d T%0d PLI_MEM_STACK tid=%d Suppress for IO ASI",mycid,sta_tid,sta_tnum);
7426 end // }
7427 end // }
7428
7429 end // if (store_ack_w[i]) }
7430 end // for }
7431
7432 end // if (store_ack_w) }
7433
7434 //----------------------------------------------------------
7435 //----------------------------------------------------------
7436 // Store Inv
7437
7438 if (store_inv_w) begin // {
7439
7440 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stinv_tnum_w]) begin // {
7441 `PR_INFO ("pli_ldst", `INFO,
7442 "C%0d PLI_MEM_STINV tid=%d pa=%h cid=%h ts=%0d",
7443 mycid,stinv_tnum_w,store_pa_w,mycid,tstamp);
7444 junk = $sim_send(`PLI_MEM_ST_INV,mycid,stinv_tnum_w,store_pa_w,tstamp);
7445 end // }
7446
7447 end // }
7448
7449
7450 //----------------------------------------------------------
7451 //----------------------------------------------------------
7452 // Store Update
7453
7454 if (store_update_w) begin // {
7455
7456 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[stu_tnum_w]) begin // {
7457 `PR_INFO ("pli_ldst", `INFO,
7458 "C%0d T%0d PLI_MEM_STUP tid=%d pa=%h ts=%0d",
7459 mycid,stu_tid_w,stu_tnum_w,store_pa_w,tstamp);
7460 junk = $sim_send(`PLI_MEM_ST_UPDATE,stu_tnum_w,store_pa_w,tstamp);
7461 end // }
7462
7463 end // }
7464
7465 //----------------------------------------------------------
7466 //----------------------------------------------------------
7467 // Load Fill
7468
7469 if (load_fill_w) begin // {
7470
7471 ldf_tnum_w = {mycid,ldf_tid_w};
7472
7473 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[ldf_tnum_w]) begin // {
7474 `PR_INFO ("pli_ldst", `INFO,
7475 "C%0d T%0d PLI_MEM_LDFILL tid=%d pa=%h ts=%0d",
7476 mycid,ldf_tid_w,ldf_tnum_w,ldf_pa_w,tstamp);
7477 junk = $sim_send(`PLI_MEM_LD_FILL,ldf_tnum_w,ldf_pa_w,tstamp);
7478 end // }
7479
7480 end // }
7481
7482 //----------------------------------------------------------
7483 //----------------------------------------------------------
7484 // Store Issue
7485
7486 if (store_w) begin // {
7487
7488 if (sti_suppress==1'b0) begin // {
7489 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[sti_tnum_w]) begin // {
7490 `PR_INFO ("pli_ldst", `INFO,
7491 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h data=%h sz=%h typ=%0h ts=%0d",
7492 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
7493 junk = $sim_send(`PLI_MEM_ST_ISSUE,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,sti_itype_w,tstamp);
7494 end // }
7495
7496 end // }
7497 else begin // {
7498 `PR_INFO ("pli_ldst", `INFO,
7499 "C%0d T%0d PLI_MEM_STISSU tid=%d pa=%h Suppress for IO ASI",mycid,sti_tid_w,sti_tnum_w,sti_pa_w);
7500 end // }
7501
7502 if (`PARGS.show_memop_on) begin // {
7503 `PR_NORMAL ("pli_ldst", `NORMAL,
7504 "C%0d T%0d MEMOP_STORE tid=%d pa=%h data=%h sz=%h ts=%0d (LSU - W stage)",
7505 mycid,sti_tid_w,sti_tnum_w,sti_pa_w,sti_data_w,sti_size_w,tstamp);
7506 end // }
7507
7508 end // }
7509
7510 //----------------------------------------------------------
7511 //----------------------------------------------------------
7512 // EvictInv
7513 // Send 1-4 EvictInv messages per cycle - based on how many Dcache lines were invalidated.
7514
7515 for (i=0; i<=3; i=i+1) begin // {
7516 if (evict_inv_w[i]) begin // {
7517
7518 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on) begin // {
7519 `PR_INFO ("pli_ldst", `INFO,
7520 "C%0d PLI_MEM_EVINV cid=%d srcid=%0d ts=%0d",
7521 mycid,mycid,evict_srcid_w,tstamp);
7522 junk = $sim_send(`PLI_MEM_EVICT_INV,mycid,evict_srcid_w,tstamp);
7523 end // }
7524
7525 end // }
7526 end // }
7527
7528 //----------------------------------------------------------
7529 //----------------------------------------------------------
7530 // Load Pop - special case
7531
7532 // This is required in case of a performance monitor trap due to L2 miss.
7533 // In this case, the trap is not indicated until after the Load pkt returns to the LSU.
7534 // ldst_sync has already sent LDISSUE and LDDATA to Riesling. But, the Load is not executed.
7535 // Load Pop tells Riesling to pop the LDISSUE,LDDATA off of its queues.
7536
7537 if (perfmon & perfmon_mask[perfmon_tid]) begin // {
7538
7539 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[perfmon_tnum]) begin // {
7540 `PR_INFO ("pli_ldst", `INFO,
7541 "C%0d T%0d PLI_MEM_LDPOP tid=%d ts=%0d",
7542 mycid,perfmon_tid,perfmon_tnum,tstamp);
7543 junk = $sim_send(`PLI_MEM_LD_POP,perfmon_tnum);
7544 end // }
7545
7546 end // }
7547
7548 //----------------------------------------------------------
7549 //----------------------------------------------------------
7550 // Store Pop - special cases
7551
7552 // This is required in case of a FRF error trap (internal_proc_error) on a Block Store.
7553 // In this case, the trap is not indicated until after the 8 STISSUE has been sent to Riesling.
7554 // But, the Store is not executed.
7555 // Store Pop tells Riesling to pop the 8 STISSUE off of its queues.
7556
7557 if (bst_kill!==8'b0) begin // {
7558
7559 for (i=0;i<=7;i=i+1) begin
7560 if (bst_kill[i]==1'b1) begin
7561 bst_kill_tid = i;
7562 bst_kill_tnum = {mycid,bst_kill_tid};
7563
7564 if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[bst_kill_tnum]) begin // {
7565 `PR_INFO ("pli_ldst", `INFO,
7566 "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
7567 mycid,bst_kill_tid,bst_kill_tnum,tstamp);
7568 junk = $sim_send(`PLI_MEM_ST_POP,bst_kill_tnum);
7569 end // }
7570 end
7571 end
7572
7573 end // }
7574
7575 //--------------------
7576 // This is required for data_access_error on atomic. In this case, Riesling only cleans up the Load,
7577 // but doesn't know it is an atomic so Riesling doesn't clean up the store in its buffers.
7578 // The STPOP tells Riesling to clear the newest Store from the buffers.
7579 // It is possible to have older Stores in-flight but not newer Stores in-flight.
7580
7581// if (st_data_access_w != 8'b0) begin // {
7582//
7583// for (i=0; i<=7; i=i+1) begin // {
7584// if (st_data_access_w[i]) begin // {
7585// tmp_tid = i[2:0];
7586// tmp_tnum = {mycid,tmp_tid};
7587//
7588// if (`PARGS.nas_check_on && `PARGS.ldst_sync_on && `PARGS.th_check_enable[tmp_tnum]) begin // {
7589// `PR_INFO ("pli_ldst", `INFO,
7590// "C%0d T%0d PLI_MEM_STPOP tid=%d ts=%0d",
7591// mycid,tmp_tid,tmp_tnum,tstamp);
7592// junk = $sim_send(`PLI_MEM_ST_POP,tmp_tnum);
7593// end // }
7594// end // } if st_data_access[i]
7595// end // } for
7596// end // } if st_data_access
7597
7598end // always }
7599
7600//----------------------------------------------------------
7601// Need to model the D arrays to get PA's for store updates and invalidates
7602
7603always @ (negedge `SPC7.l2clk) begin // {
7604 if (`SPC7.lsu.dta.wr_way[0])
7605 dta_way0[`SPC7.lsu.dta.index_y[6:0]] <= `SPC7.lsu.dta.wrtag_y[27:0];
7606 if (`SPC7.lsu.dta.wr_way[1])
7607 dta_way1[`SPC7.lsu.dta.index_y[6:0]] <= `SPC7.lsu.dta.wrtag_y[27:0];
7608 if (`SPC7.lsu.dta.wr_way[2])
7609 dta_way2[`SPC7.lsu.dta.index_y[6:0]] <= `SPC7.lsu.dta.wrtag_y[27:0];
7610 if (`SPC7.lsu.dta.wr_way[3])
7611 dta_way3[`SPC7.lsu.dta.index_y[6:0]] <= `SPC7.lsu.dta.wrtag_y[27:0];
7612end // always }
7613
7614//----------------------------------------------------------
7615`endif
7616endmodule
7617
7618`endif
7619//----------------------------------------------------------
7620//----------------------------------------------------------