Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / verilog / tlb_sync / dtlb_rd.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: dtlb_rd.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 dtlb_rd_c0 (
38
39 mytg
40);
41
42`include "tlb_sync.vh"
43
44input mytg;
45`ifndef GATESIM
46
47wire rd_vld;
48wire rd_vld_b;
49reg rd_vld_w;
50reg rd_vld_w2;
51reg rd_vld_w3;
52reg [(`TS_WIDTH-1):0] tstamp;
53
54wire [3:0] select_pc_b;
55reg [3:0] select_pc_w;
56reg [3:0] select_pc_w2;
57reg [3:0] select_pc_w3;
58wire [47:0] pc_b;
59reg [47:0] pc_w;
60reg [47:0] pc_w2;
61reg [47:0] pc_w3;
62
63wire irf_error_m;
64wire irf_error_b;
65reg irf_error_b_pre;
66
67reg [2:0] mycid;
68reg [2:0] mytid;
69reg [5:0] mytnum;
70reg ready;
71
72reg [2:0] bsktid;
73reg [5:0] bsktnum;
74
75integer i;
76integer junk;
77wire lsuErrorInB;
78
79reg [7:0] dtlbReadActive;
80wire [7:0] blockStoreKill;
81
82wire [2:0] myLateErrTid = `SPC0.lsu_dcerr_tid_g[2:0];
83wire [5:0] myLateErrTnum = (mycid * 8) + myLateErrTid;
84
85initial begin // {
86 ready = 0;
87 dtlbReadActive = 8'h0;
88
89 @(posedge `SPC0.l2clk) ;
90 @(posedge `SPC0.l2clk) ;
91 ready = `PARGS.tlb_sync_on;
92 mycid = 0;
93end //}
94
95//----------------------------------------------------------
96// DUT probes
97
98
99// I use this signal to get several standard errors in LSU that can happen
100// that will cause a DTLB_READ, and use them to make sure they are not
101// happening with perfom trap in the rd_vld_b signal
102wire lsuErrorB;
103assign lsuErrorB = (`SPC0.lsu.dcc.lsu_align_b |
104 `SPC0.lsu.dcc.lsu_lddf_align_b |
105 `SPC0.lsu.dcc.lsu_stdf_align_b |
106 `SPC0.lsu.dcc.lsu_dae_invalid_asi_b |
107 `SPC0.lsu.dcc.lsu_dae_nc_page_b |
108 `SPC0.lsu.dcc.lsu_dae_nfo_page_b |
109 `SPC0.lsu.dcc.lsu_dae_priv_viol_b |
110 `SPC0.lsu.dcc.lsu_dae_so_page |
111 `SPC0.lsu.dcc.lsu_priv_action_b |
112 `SPC0.lsu.dcc.lsu_va_watchpoint_b |
113 `SPC0.lsu.dcc.lsu_pa_watchpoint_b |
114 `SPC0.lsu.dcc.lsu_daccess_prot_b |
115 `SPC0.lsu.dcc.lsu_dttp_err_b |
116 `SPC0.lsu.dcc.lsu_dtdp_err_b |
117 `SPC0.lsu.dcc.lsu_dtmh_err_b);
118
119
120// Per tlb_sync spec, high priority (0-9) exceptions should not send DTLBREAD.
121// tlu_flush_lsu_b - suppress DTLBREAD for high priority (0-9) exceptions.
122// However, VA_watchpoint (TT=0x62, priority 11) also causes tlu_flush_lsu_b to be asserted.
123// va_watchpoint_w_in was added to allow DTLBREAD to be sent even though tlu_flush_lsu_b fires.
124// fgu_error_b - suppress DTLBREAD on FRF errors.
125// irf_error_b - suppress DTLBREAD on IRF errors.
126
127assign select_pc_b = mytg ? `PROBES0.select_pc_b[7:4] : `PROBES0.select_pc_b[3:0];
128assign rd_vld_b = mytg ?
129
130 (`PROBES0.tlb_rd_vld_b &&
131 !`PROBES0.tlb_bypass_b &&
132 !`SPC0.lsu.lsu_illegal_inst_b &&
133 !`SPC0.lsu.dcc.fgu_error_b &&
134 !irf_error_b &&
135 !(`SPC0.lsu_perfmon_trap_b & `SPC0.tlu.fls1.pil_mask_15_b & ~lsuErrorB) &&
136 !`SPC0.lsu.dcc.pipe_flush_b &&
137 (!`SPC0.tlu_flush_lsu_b | `SPC0.tlu.fls1.va_watchpoint_w_in) &&
138 `SPC0.tlu.fls1.lsu_inst_b &&
139 (|select_pc_b)) :
140
141 (`PROBES0.tlb_rd_vld_b &&
142 !`PROBES0.tlb_bypass_b &&
143 !`SPC0.lsu.lsu_illegal_inst_b &&
144 !`SPC0.lsu.dcc.fgu_error_b &&
145 !irf_error_b &&
146 !(`SPC0.lsu_perfmon_trap_b & `SPC0.tlu.fls0.pil_mask_15_b & ~lsuErrorB) &&
147 !`SPC0.lsu.dcc.pipe_flush_b &&
148 (!`SPC0.tlu_flush_lsu_b | `SPC0.tlu.fls0.va_watchpoint_w_in) &&
149 `SPC0.tlu.fls0.lsu_inst_b &&
150 (|select_pc_b));
151
152
153assign blockStoreKill = {`SPC0.lsu.sbs7.bst_kill,
154 `SPC0.lsu.sbs6.bst_kill,
155 `SPC0.lsu.sbs5.bst_kill,
156 `SPC0.lsu.sbs4.bst_kill,
157 `SPC0.lsu.sbs3.bst_kill,
158 `SPC0.lsu.sbs2.bst_kill,
159 `SPC0.lsu.sbs1.bst_kill,
160 `SPC0.lsu.sbs0.bst_kill};
161
162
163
164
165
166
167// suppress DTLBREAD on STB errors.
168assign rd_vld = rd_vld_w3 &&
169 !(`SPC0.lsu.lmc.sbdlc_err | `SPC0.lsu.lmc.sbdlu_err);
170
171// suppress DTLBREAD on IRF errors
172assign irf_error_m = (`SPC0.lsu.dcc.tid_m[2] ? `SPC0.exu_ecc_m[1] : `SPC0.exu_ecc_m[0]);
173assign irf_error_b = irf_error_b_pre |
174 ((`SPC0.lsu.dcc.tid_b[2] ? `SPC0.lsu.dcc.exu_ecc_m[1] :
175 `SPC0.lsu.dcc.exu_ecc_m[0]) &
176 `SPC0.lsu.dcc.twocycle_b &
177
178 ~(`SPC0.lsu.dcc.lsu_align_b |
179 `SPC0.lsu.dcc.lsu_lddf_align_b |
180 `SPC0.lsu.dcc.lsu_stdf_align_b |
181 `SPC0.lsu.dcc.lsu_dae_invalid_asi_b |
182 `SPC0.lsu.dcc.lsu_dae_nc_page_b |
183 `SPC0.lsu.dcc.lsu_dae_nfo_page_b |
184 `SPC0.lsu.dcc.lsu_dae_priv_viol_b |
185 `SPC0.lsu.dcc.lsu_dae_so_page |
186 `SPC0.lsu.dcc.lsu_priv_action_b |
187 `SPC0.lsu.dcc.lsu_va_watchpoint_b |
188 `SPC0.lsu.dcc.lsu_pa_watchpoint_b |
189 ~`SPC0.lsu.dcc.lsu_tlb_miss_b_ |
190 `SPC0.lsu.dcc.lsu_daccess_prot_b |
191 `SPC0.lsu.dcc.lsu_dttp_err_b |
192 `SPC0.lsu.dcc.lsu_dtdp_err_b |
193 `SPC0.lsu.dcc.lsu_dtmh_err_b));
194
195
196
197assign pc_b = mytg ? `PROBES0.pc_1_b :
198 `PROBES0.pc_0_b;
199
200//----------------------------------------------------------
201// Send Command to NAS
202
203always @ (posedge `SPC0.l2clk & ready) begin // {
204
205 // if POR|WMR, then no TLBread
206 if (`TOP.in_reset_core) begin // {
207
208 // flush pipeline during reset
209 irf_error_b_pre <= 0;
210
211 rd_vld_w <= 0;
212 rd_vld_w2 <= 0;
213 rd_vld_w3 <= 0;
214
215 select_pc_w <= 0;
216 select_pc_w2 <= 0;
217 select_pc_w3 <= 0;
218
219 pc_w <= 0;
220 pc_w2 <= 0;
221 pc_w3 <= 0;
222
223 end // }
224 else begin // {
225
226 tstamp = `TOP.core_cycle_cnt;
227
228 irf_error_b_pre <= irf_error_m;
229
230 rd_vld_w <= rd_vld_b;
231 rd_vld_w2 <= rd_vld_w;
232 rd_vld_w3 <= rd_vld_w2;
233
234 select_pc_w <= select_pc_b;
235 select_pc_w2 <= select_pc_w;
236 select_pc_w3 <= select_pc_w2;
237
238 pc_w <= pc_b;
239 pc_w2 <= pc_w;
240 pc_w3 <= pc_w2;
241
242 //---------------------------------
243 if (rd_vld) begin // {
244
245 // Determine which thread is active
246 for (i=0; i<=3; i=i+1) begin // {
247 if (select_pc_w3[i]==1'b1) begin // {
248 mytid = i + (mytg*4);
249 mytnum = (mycid * 8) + mytid;
250 end // }
251 end // }
252
253
254 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
255 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD tid=%d pc=%h ts=%0d",
256 mycid,mytid,mytnum,pc_w3,tstamp-5);
257 junk = $sim_send(`PLI_DTLBREAD, mytnum, tstamp-5);
258
259 //--------------------
260 if (`PARGS.show_tlb_on) begin // {
261 $display ("SHOW_TLB: DTLB_READ C%0d T%0d pc=%h ts=%0d",
262 mycid,mytid,pc_w3,(tstamp-5)*`TOP.core_period);
263 end //}
264
265 end //}
266
267 end // }
268 end // in_reset}
269
270end // always }
271
272
273//---------------------------------------------------------
274// DTLB POP state machine
275
276always @ (posedge `SPC0.l2clk & ready) begin // {
277
278 // if POR|WMR, then no TLBread
279 if (!`TOP.in_reset_core) begin // {
280
281 //Set read active when there is a valid lookup
282 if (rd_vld_b) begin // {
283 dtlbReadActive[`SPC0.lsu.dcc.tid_b[2:0]] <= 1'h1;
284 end //}
285
286 //Clear it when there is a bypass
287 if ((`SPC0.lsu.dcc.ld_inst_vld_b |
288 `SPC0.lsu.dcc.st_inst_vld_b) &
289 `SPC0.lsu.dcc.tlb_bypass_b &
290 ~`SPC0.lsu.dcc.flush_all_b) begin // {
291 dtlbReadActive[`SPC0.lsu.dcc.tid_b[2:0]] <= 1'h0;
292 end //}
293
294 //Do a pop if we are active and then see a Perf Mon
295 if ((`SPC0.lsu_perfmon_trap_g |
296 `SPC0.lsu_dcl2u_err_g |
297 `SPC0.lsu_dcl2nd_err_g) &
298 dtlbReadActive[`SPC0.lsu_dcerr_tid_g[2:0]]) begin // {
299 dtlbReadActive[`SPC0.lsu_dcerr_tid_g[2:0]] = 1'h0;
300
301 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
302 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
303 mycid,myLateErrTid,myLateErrTnum,tstamp);
304 junk = $sim_send(`PLI_DTLBREAD_POP, myLateErrTnum, tstamp);
305
306 //--------------------
307 if (`PARGS.show_tlb_on) begin // {
308 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
309 mycid,mytid,tstamp*`TOP.core_period);
310 end //}
311 end //}
312 end //}
313
314 // Determine which thread is active
315 for (i=0; i<=3; i=i+1) begin // {
316 bsktid = i + (mytg*4);
317 bsktnum = (mycid * 8) + bsktid;
318
319 //Do a pop if we see a block storke kill
320 if (blockStoreKill[bsktid] &
321 dtlbReadActive[bsktid]) begin // {
322 dtlbReadActive[bsktid] = 1'h0;
323
324 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
325 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
326 mycid,bsktid,bsktnum,tstamp);
327 junk = $sim_send(`PLI_DTLBREAD_POP, bsktnum, tstamp);
328
329 //--------------------
330 if (`PARGS.show_tlb_on) begin // {
331 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
332 mycid,bsktid,tstamp*`TOP.core_period);
333 end //}
334 end // }
335 end // }
336
337 end // for }
338
339 end // in_reset}
340end // always}
341
342
343
344//----------------------------------------------------------
345`endif
346endmodule
347
348`endif
349`ifdef CORE_1
350
351module dtlb_rd_c1 (
352
353 mytg
354);
355
356`include "tlb_sync.vh"
357
358input mytg;
359`ifndef GATESIM
360
361wire rd_vld;
362wire rd_vld_b;
363reg rd_vld_w;
364reg rd_vld_w2;
365reg rd_vld_w3;
366reg [(`TS_WIDTH-1):0] tstamp;
367
368wire [3:0] select_pc_b;
369reg [3:0] select_pc_w;
370reg [3:0] select_pc_w2;
371reg [3:0] select_pc_w3;
372wire [47:0] pc_b;
373reg [47:0] pc_w;
374reg [47:0] pc_w2;
375reg [47:0] pc_w3;
376
377wire irf_error_m;
378wire irf_error_b;
379reg irf_error_b_pre;
380
381reg [2:0] mycid;
382reg [2:0] mytid;
383reg [5:0] mytnum;
384reg ready;
385
386reg [2:0] bsktid;
387reg [5:0] bsktnum;
388
389integer i;
390integer junk;
391wire lsuErrorInB;
392
393reg [7:0] dtlbReadActive;
394wire [7:0] blockStoreKill;
395
396wire [2:0] myLateErrTid = `SPC1.lsu_dcerr_tid_g[2:0];
397wire [5:0] myLateErrTnum = (mycid * 8) + myLateErrTid;
398
399initial begin // {
400 ready = 0;
401 dtlbReadActive = 8'h0;
402
403 @(posedge `SPC1.l2clk) ;
404 @(posedge `SPC1.l2clk) ;
405 ready = `PARGS.tlb_sync_on;
406 mycid = 1;
407end //}
408
409//----------------------------------------------------------
410// DUT probes
411
412
413// I use this signal to get several standard errors in LSU that can happen
414// that will cause a DTLB_READ, and use them to make sure they are not
415// happening with perfom trap in the rd_vld_b signal
416assign lsuErrorB = (`SPC1.lsu.dcc.lsu_align_b |
417 `SPC1.lsu.dcc.lsu_lddf_align_b |
418 `SPC1.lsu.dcc.lsu_stdf_align_b |
419 `SPC1.lsu.dcc.lsu_dae_invalid_asi_b |
420 `SPC1.lsu.dcc.lsu_dae_nc_page_b |
421 `SPC1.lsu.dcc.lsu_dae_nfo_page_b |
422 `SPC1.lsu.dcc.lsu_dae_priv_viol_b |
423 `SPC1.lsu.dcc.lsu_dae_so_page |
424 `SPC1.lsu.dcc.lsu_priv_action_b |
425 `SPC1.lsu.dcc.lsu_va_watchpoint_b |
426 `SPC1.lsu.dcc.lsu_pa_watchpoint_b |
427 `SPC1.lsu.dcc.lsu_daccess_prot_b |
428 `SPC1.lsu.dcc.lsu_dttp_err_b |
429 `SPC1.lsu.dcc.lsu_dtdp_err_b |
430 `SPC1.lsu.dcc.lsu_dtmh_err_b);
431
432
433// Per tlb_sync spec, high priority (0-9) exceptions should not send DTLBREAD.
434// tlu_flush_lsu_b - suppress DTLBREAD for high priority (0-9) exceptions.
435// However, VA_watchpoint (TT=0x62, priority 11) also causes tlu_flush_lsu_b to be asserted.
436// va_watchpoint_w_in was added to allow DTLBREAD to be sent even though tlu_flush_lsu_b fires.
437// fgu_error_b - suppress DTLBREAD on FRF errors.
438// irf_error_b - suppress DTLBREAD on IRF errors.
439
440assign select_pc_b = mytg ? `PROBES1.select_pc_b[7:4] : `PROBES1.select_pc_b[3:0];
441assign rd_vld_b = mytg ?
442
443 (`PROBES1.tlb_rd_vld_b &&
444 !`PROBES1.tlb_bypass_b &&
445 !`SPC1.lsu.lsu_illegal_inst_b &&
446 !`SPC1.lsu.dcc.fgu_error_b &&
447 !irf_error_b &&
448 !(`SPC1.lsu_perfmon_trap_b & `SPC1.tlu.fls1.pil_mask_15_b & ~lsuErrorB) &&
449 !`SPC1.lsu.dcc.pipe_flush_b &&
450 (!`SPC1.tlu_flush_lsu_b | `SPC1.tlu.fls1.va_watchpoint_w_in) &&
451 `SPC1.tlu.fls1.lsu_inst_b &&
452 (|select_pc_b)) :
453
454 (`PROBES1.tlb_rd_vld_b &&
455 !`PROBES1.tlb_bypass_b &&
456 !`SPC1.lsu.lsu_illegal_inst_b &&
457 !`SPC1.lsu.dcc.fgu_error_b &&
458 !irf_error_b &&
459 !(`SPC1.lsu_perfmon_trap_b & `SPC1.tlu.fls0.pil_mask_15_b & ~lsuErrorB) &&
460 !`SPC1.lsu.dcc.pipe_flush_b &&
461 (!`SPC1.tlu_flush_lsu_b | `SPC1.tlu.fls0.va_watchpoint_w_in) &&
462 `SPC1.tlu.fls0.lsu_inst_b &&
463 (|select_pc_b));
464
465
466assign blockStoreKill = {`SPC1.lsu.sbs7.bst_kill,
467 `SPC1.lsu.sbs6.bst_kill,
468 `SPC1.lsu.sbs5.bst_kill,
469 `SPC1.lsu.sbs4.bst_kill,
470 `SPC1.lsu.sbs3.bst_kill,
471 `SPC1.lsu.sbs2.bst_kill,
472 `SPC1.lsu.sbs1.bst_kill,
473 `SPC1.lsu.sbs0.bst_kill};
474
475
476
477
478
479
480// suppress DTLBREAD on STB errors.
481assign rd_vld = rd_vld_w3 &&
482 !(`SPC1.lsu.lmc.sbdlc_err | `SPC1.lsu.lmc.sbdlu_err);
483
484// suppress DTLBREAD on IRF errors
485assign irf_error_m = (`SPC1.lsu.dcc.tid_m[2] ? `SPC1.exu_ecc_m[1] : `SPC1.exu_ecc_m[0]);
486assign irf_error_b = irf_error_b_pre |
487 ((`SPC1.lsu.dcc.tid_b[2] ? `SPC1.lsu.dcc.exu_ecc_m[1] :
488 `SPC1.lsu.dcc.exu_ecc_m[0]) &
489 `SPC1.lsu.dcc.twocycle_b &
490
491 ~(`SPC1.lsu.dcc.lsu_align_b |
492 `SPC1.lsu.dcc.lsu_lddf_align_b |
493 `SPC1.lsu.dcc.lsu_stdf_align_b |
494 `SPC1.lsu.dcc.lsu_dae_invalid_asi_b |
495 `SPC1.lsu.dcc.lsu_dae_nc_page_b |
496 `SPC1.lsu.dcc.lsu_dae_nfo_page_b |
497 `SPC1.lsu.dcc.lsu_dae_priv_viol_b |
498 `SPC1.lsu.dcc.lsu_dae_so_page |
499 `SPC1.lsu.dcc.lsu_priv_action_b |
500 `SPC1.lsu.dcc.lsu_va_watchpoint_b |
501 `SPC1.lsu.dcc.lsu_pa_watchpoint_b |
502 ~`SPC1.lsu.dcc.lsu_tlb_miss_b_ |
503 `SPC1.lsu.dcc.lsu_daccess_prot_b |
504 `SPC1.lsu.dcc.lsu_dttp_err_b |
505 `SPC1.lsu.dcc.lsu_dtdp_err_b |
506 `SPC1.lsu.dcc.lsu_dtmh_err_b));
507
508
509
510assign pc_b = mytg ? `PROBES1.pc_1_b :
511 `PROBES1.pc_0_b;
512
513//----------------------------------------------------------
514// Send Command to NAS
515
516always @ (posedge `SPC1.l2clk & ready) begin // {
517
518 // if POR|WMR, then no TLBread
519 if (`TOP.in_reset_core) begin // {
520
521 // flush pipeline during reset
522 irf_error_b_pre <= 0;
523
524 rd_vld_w <= 0;
525 rd_vld_w2 <= 0;
526 rd_vld_w3 <= 0;
527
528 select_pc_w <= 0;
529 select_pc_w2 <= 0;
530 select_pc_w3 <= 0;
531
532 pc_w <= 0;
533 pc_w2 <= 0;
534 pc_w3 <= 0;
535
536 end // }
537 else begin // {
538
539 tstamp = `TOP.core_cycle_cnt;
540
541 irf_error_b_pre <= irf_error_m;
542
543 rd_vld_w <= rd_vld_b;
544 rd_vld_w2 <= rd_vld_w;
545 rd_vld_w3 <= rd_vld_w2;
546
547 select_pc_w <= select_pc_b;
548 select_pc_w2 <= select_pc_w;
549 select_pc_w3 <= select_pc_w2;
550
551 pc_w <= pc_b;
552 pc_w2 <= pc_w;
553 pc_w3 <= pc_w2;
554
555 //---------------------------------
556 if (rd_vld) begin // {
557
558 // Determine which thread is active
559 for (i=0; i<=3; i=i+1) begin // {
560 if (select_pc_w3[i]==1'b1) begin // {
561 mytid = i + (mytg*4);
562 mytnum = (mycid * 8) + mytid;
563 end // }
564 end // }
565
566
567 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
568 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD tid=%d pc=%h ts=%0d",
569 mycid,mytid,mytnum,pc_w3,tstamp-5);
570 junk = $sim_send(`PLI_DTLBREAD, mytnum, tstamp-5);
571
572 //--------------------
573 if (`PARGS.show_tlb_on) begin // {
574 $display ("SHOW_TLB: DTLB_READ C%0d T%0d pc=%h ts=%0d",
575 mycid,mytid,pc_w3,(tstamp-5)*`TOP.core_period);
576 end //}
577
578 end //}
579
580 end // }
581 end // in_reset}
582
583end // always }
584
585
586//---------------------------------------------------------
587// DTLB POP state machine
588
589always @ (posedge `SPC1.l2clk & ready) begin // {
590
591 // if POR|WMR, then no TLBread
592 if (!`TOP.in_reset_core) begin // {
593
594 //Set read active when there is a valid lookup
595 if (rd_vld_b) begin // {
596 dtlbReadActive[`SPC1.lsu.dcc.tid_b[2:0]] <= 1'h1;
597 end //}
598
599 //Clear it when there is a bypass
600 if ((`SPC1.lsu.dcc.ld_inst_vld_b |
601 `SPC1.lsu.dcc.st_inst_vld_b) &
602 `SPC1.lsu.dcc.tlb_bypass_b &
603 ~`SPC1.lsu.dcc.flush_all_b) begin // {
604 dtlbReadActive[`SPC1.lsu.dcc.tid_b[2:0]] <= 1'h0;
605 end //}
606
607 //Do a pop if we are active and then see a Perf Mon
608 if ((`SPC1.lsu_perfmon_trap_g |
609 `SPC1.lsu_dcl2u_err_g |
610 `SPC1.lsu_dcl2nd_err_g) &
611 dtlbReadActive[`SPC1.lsu_dcerr_tid_g[2:0]]) begin // {
612 dtlbReadActive[`SPC1.lsu_dcerr_tid_g[2:0]] = 1'h0;
613
614 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
615 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
616 mycid,myLateErrTid,myLateErrTnum,tstamp);
617 junk = $sim_send(`PLI_DTLBREAD_POP, myLateErrTnum, tstamp);
618
619 //--------------------
620 if (`PARGS.show_tlb_on) begin // {
621 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
622 mycid,mytid,tstamp*`TOP.core_period);
623 end //}
624 end //}
625 end //}
626
627 // Determine which thread is active
628 for (i=0; i<=3; i=i+1) begin // {
629 bsktid = i + (mytg*4);
630 bsktnum = (mycid * 8) + bsktid;
631
632 //Do a pop if we see a block storke kill
633 if (blockStoreKill[bsktid] &
634 dtlbReadActive[bsktid]) begin // {
635 dtlbReadActive[bsktid] = 1'h0;
636
637 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
638 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
639 mycid,bsktid,bsktnum,tstamp);
640 junk = $sim_send(`PLI_DTLBREAD_POP, bsktnum, tstamp);
641
642 //--------------------
643 if (`PARGS.show_tlb_on) begin // {
644 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
645 mycid,bsktid,tstamp*`TOP.core_period);
646 end //}
647 end // }
648 end // }
649
650 end // for }
651
652 end // in_reset}
653end // always}
654
655
656
657//----------------------------------------------------------
658`endif
659endmodule
660
661`endif
662`ifdef CORE_2
663
664module dtlb_rd_c2 (
665
666 mytg
667);
668
669`include "tlb_sync.vh"
670
671input mytg;
672`ifndef GATESIM
673
674wire rd_vld;
675wire rd_vld_b;
676reg rd_vld_w;
677reg rd_vld_w2;
678reg rd_vld_w3;
679reg [(`TS_WIDTH-1):0] tstamp;
680
681wire [3:0] select_pc_b;
682reg [3:0] select_pc_w;
683reg [3:0] select_pc_w2;
684reg [3:0] select_pc_w3;
685wire [47:0] pc_b;
686reg [47:0] pc_w;
687reg [47:0] pc_w2;
688reg [47:0] pc_w3;
689
690wire irf_error_m;
691wire irf_error_b;
692reg irf_error_b_pre;
693
694reg [2:0] mycid;
695reg [2:0] mytid;
696reg [5:0] mytnum;
697reg ready;
698
699reg [2:0] bsktid;
700reg [5:0] bsktnum;
701
702integer i;
703integer junk;
704wire lsuErrorInB;
705
706reg [7:0] dtlbReadActive;
707wire [7:0] blockStoreKill;
708
709wire [2:0] myLateErrTid = `SPC2.lsu_dcerr_tid_g[2:0];
710wire [5:0] myLateErrTnum = (mycid * 8) + myLateErrTid;
711
712initial begin // {
713 ready = 0;
714 dtlbReadActive = 8'h0;
715
716 @(posedge `SPC2.l2clk) ;
717 @(posedge `SPC2.l2clk) ;
718 ready = `PARGS.tlb_sync_on;
719 mycid = 2;
720end //}
721
722//----------------------------------------------------------
723// DUT probes
724
725
726// I use this signal to get several standard errors in LSU that can happen
727// that will cause a DTLB_READ, and use them to make sure they are not
728// happening with perfom trap in the rd_vld_b signal
729assign lsuErrorB = (`SPC2.lsu.dcc.lsu_align_b |
730 `SPC2.lsu.dcc.lsu_lddf_align_b |
731 `SPC2.lsu.dcc.lsu_stdf_align_b |
732 `SPC2.lsu.dcc.lsu_dae_invalid_asi_b |
733 `SPC2.lsu.dcc.lsu_dae_nc_page_b |
734 `SPC2.lsu.dcc.lsu_dae_nfo_page_b |
735 `SPC2.lsu.dcc.lsu_dae_priv_viol_b |
736 `SPC2.lsu.dcc.lsu_dae_so_page |
737 `SPC2.lsu.dcc.lsu_priv_action_b |
738 `SPC2.lsu.dcc.lsu_va_watchpoint_b |
739 `SPC2.lsu.dcc.lsu_pa_watchpoint_b |
740 `SPC2.lsu.dcc.lsu_daccess_prot_b |
741 `SPC2.lsu.dcc.lsu_dttp_err_b |
742 `SPC2.lsu.dcc.lsu_dtdp_err_b |
743 `SPC2.lsu.dcc.lsu_dtmh_err_b);
744
745
746// Per tlb_sync spec, high priority (0-9) exceptions should not send DTLBREAD.
747// tlu_flush_lsu_b - suppress DTLBREAD for high priority (0-9) exceptions.
748// However, VA_watchpoint (TT=0x62, priority 11) also causes tlu_flush_lsu_b to be asserted.
749// va_watchpoint_w_in was added to allow DTLBREAD to be sent even though tlu_flush_lsu_b fires.
750// fgu_error_b - suppress DTLBREAD on FRF errors.
751// irf_error_b - suppress DTLBREAD on IRF errors.
752
753assign select_pc_b = mytg ? `PROBES2.select_pc_b[7:4] : `PROBES2.select_pc_b[3:0];
754assign rd_vld_b = mytg ?
755
756 (`PROBES2.tlb_rd_vld_b &&
757 !`PROBES2.tlb_bypass_b &&
758 !`SPC2.lsu.lsu_illegal_inst_b &&
759 !`SPC2.lsu.dcc.fgu_error_b &&
760 !irf_error_b &&
761 !(`SPC2.lsu_perfmon_trap_b & `SPC2.tlu.fls1.pil_mask_15_b & ~lsuErrorB) &&
762 !`SPC2.lsu.dcc.pipe_flush_b &&
763 (!`SPC2.tlu_flush_lsu_b | `SPC2.tlu.fls1.va_watchpoint_w_in) &&
764 `SPC2.tlu.fls1.lsu_inst_b &&
765 (|select_pc_b)) :
766
767 (`PROBES2.tlb_rd_vld_b &&
768 !`PROBES2.tlb_bypass_b &&
769 !`SPC2.lsu.lsu_illegal_inst_b &&
770 !`SPC2.lsu.dcc.fgu_error_b &&
771 !irf_error_b &&
772 !(`SPC2.lsu_perfmon_trap_b & `SPC2.tlu.fls0.pil_mask_15_b & ~lsuErrorB) &&
773 !`SPC2.lsu.dcc.pipe_flush_b &&
774 (!`SPC2.tlu_flush_lsu_b | `SPC2.tlu.fls0.va_watchpoint_w_in) &&
775 `SPC2.tlu.fls0.lsu_inst_b &&
776 (|select_pc_b));
777
778
779assign blockStoreKill = {`SPC2.lsu.sbs7.bst_kill,
780 `SPC2.lsu.sbs6.bst_kill,
781 `SPC2.lsu.sbs5.bst_kill,
782 `SPC2.lsu.sbs4.bst_kill,
783 `SPC2.lsu.sbs3.bst_kill,
784 `SPC2.lsu.sbs2.bst_kill,
785 `SPC2.lsu.sbs1.bst_kill,
786 `SPC2.lsu.sbs0.bst_kill};
787
788
789
790
791
792
793// suppress DTLBREAD on STB errors.
794assign rd_vld = rd_vld_w3 &&
795 !(`SPC2.lsu.lmc.sbdlc_err | `SPC2.lsu.lmc.sbdlu_err);
796
797// suppress DTLBREAD on IRF errors
798assign irf_error_m = (`SPC2.lsu.dcc.tid_m[2] ? `SPC2.exu_ecc_m[1] : `SPC2.exu_ecc_m[0]);
799assign irf_error_b = irf_error_b_pre |
800 ((`SPC2.lsu.dcc.tid_b[2] ? `SPC2.lsu.dcc.exu_ecc_m[1] :
801 `SPC2.lsu.dcc.exu_ecc_m[0]) &
802 `SPC2.lsu.dcc.twocycle_b &
803
804 ~(`SPC2.lsu.dcc.lsu_align_b |
805 `SPC2.lsu.dcc.lsu_lddf_align_b |
806 `SPC2.lsu.dcc.lsu_stdf_align_b |
807 `SPC2.lsu.dcc.lsu_dae_invalid_asi_b |
808 `SPC2.lsu.dcc.lsu_dae_nc_page_b |
809 `SPC2.lsu.dcc.lsu_dae_nfo_page_b |
810 `SPC2.lsu.dcc.lsu_dae_priv_viol_b |
811 `SPC2.lsu.dcc.lsu_dae_so_page |
812 `SPC2.lsu.dcc.lsu_priv_action_b |
813 `SPC2.lsu.dcc.lsu_va_watchpoint_b |
814 `SPC2.lsu.dcc.lsu_pa_watchpoint_b |
815 ~`SPC2.lsu.dcc.lsu_tlb_miss_b_ |
816 `SPC2.lsu.dcc.lsu_daccess_prot_b |
817 `SPC2.lsu.dcc.lsu_dttp_err_b |
818 `SPC2.lsu.dcc.lsu_dtdp_err_b |
819 `SPC2.lsu.dcc.lsu_dtmh_err_b));
820
821
822
823assign pc_b = mytg ? `PROBES2.pc_1_b :
824 `PROBES2.pc_0_b;
825
826//----------------------------------------------------------
827// Send Command to NAS
828
829always @ (posedge `SPC2.l2clk & ready) begin // {
830
831 // if POR|WMR, then no TLBread
832 if (`TOP.in_reset_core) begin // {
833
834 // flush pipeline during reset
835 irf_error_b_pre <= 0;
836
837 rd_vld_w <= 0;
838 rd_vld_w2 <= 0;
839 rd_vld_w3 <= 0;
840
841 select_pc_w <= 0;
842 select_pc_w2 <= 0;
843 select_pc_w3 <= 0;
844
845 pc_w <= 0;
846 pc_w2 <= 0;
847 pc_w3 <= 0;
848
849 end // }
850 else begin // {
851
852 tstamp = `TOP.core_cycle_cnt;
853
854 irf_error_b_pre <= irf_error_m;
855
856 rd_vld_w <= rd_vld_b;
857 rd_vld_w2 <= rd_vld_w;
858 rd_vld_w3 <= rd_vld_w2;
859
860 select_pc_w <= select_pc_b;
861 select_pc_w2 <= select_pc_w;
862 select_pc_w3 <= select_pc_w2;
863
864 pc_w <= pc_b;
865 pc_w2 <= pc_w;
866 pc_w3 <= pc_w2;
867
868 //---------------------------------
869 if (rd_vld) begin // {
870
871 // Determine which thread is active
872 for (i=0; i<=3; i=i+1) begin // {
873 if (select_pc_w3[i]==1'b1) begin // {
874 mytid = i + (mytg*4);
875 mytnum = (mycid * 8) + mytid;
876 end // }
877 end // }
878
879
880 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
881 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD tid=%d pc=%h ts=%0d",
882 mycid,mytid,mytnum,pc_w3,tstamp-5);
883 junk = $sim_send(`PLI_DTLBREAD, mytnum, tstamp-5);
884
885 //--------------------
886 if (`PARGS.show_tlb_on) begin // {
887 $display ("SHOW_TLB: DTLB_READ C%0d T%0d pc=%h ts=%0d",
888 mycid,mytid,pc_w3,(tstamp-5)*`TOP.core_period);
889 end //}
890
891 end //}
892
893 end // }
894 end // in_reset}
895
896end // always }
897
898
899//---------------------------------------------------------
900// DTLB POP state machine
901
902always @ (posedge `SPC2.l2clk & ready) begin // {
903
904 // if POR|WMR, then no TLBread
905 if (!`TOP.in_reset_core) begin // {
906
907 //Set read active when there is a valid lookup
908 if (rd_vld_b) begin // {
909 dtlbReadActive[`SPC2.lsu.dcc.tid_b[2:0]] <= 1'h1;
910 end //}
911
912 //Clear it when there is a bypass
913 if ((`SPC2.lsu.dcc.ld_inst_vld_b |
914 `SPC2.lsu.dcc.st_inst_vld_b) &
915 `SPC2.lsu.dcc.tlb_bypass_b &
916 ~`SPC2.lsu.dcc.flush_all_b) begin // {
917 dtlbReadActive[`SPC2.lsu.dcc.tid_b[2:0]] <= 1'h0;
918 end //}
919
920 //Do a pop if we are active and then see a Perf Mon
921 if ((`SPC2.lsu_perfmon_trap_g |
922 `SPC2.lsu_dcl2u_err_g |
923 `SPC2.lsu_dcl2nd_err_g) &
924 dtlbReadActive[`SPC2.lsu_dcerr_tid_g[2:0]]) begin // {
925 dtlbReadActive[`SPC2.lsu_dcerr_tid_g[2:0]] = 1'h0;
926
927 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
928 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
929 mycid,myLateErrTid,myLateErrTnum,tstamp);
930 junk = $sim_send(`PLI_DTLBREAD_POP, myLateErrTnum, tstamp);
931
932 //--------------------
933 if (`PARGS.show_tlb_on) begin // {
934 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
935 mycid,mytid,tstamp*`TOP.core_period);
936 end //}
937 end //}
938 end //}
939
940 // Determine which thread is active
941 for (i=0; i<=3; i=i+1) begin // {
942 bsktid = i + (mytg*4);
943 bsktnum = (mycid * 8) + bsktid;
944
945 //Do a pop if we see a block storke kill
946 if (blockStoreKill[bsktid] &
947 dtlbReadActive[bsktid]) begin // {
948 dtlbReadActive[bsktid] = 1'h0;
949
950 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
951 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
952 mycid,bsktid,bsktnum,tstamp);
953 junk = $sim_send(`PLI_DTLBREAD_POP, bsktnum, tstamp);
954
955 //--------------------
956 if (`PARGS.show_tlb_on) begin // {
957 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
958 mycid,bsktid,tstamp*`TOP.core_period);
959 end //}
960 end // }
961 end // }
962
963 end // for }
964
965 end // in_reset}
966end // always}
967
968
969
970//----------------------------------------------------------
971`endif
972endmodule
973
974`endif
975`ifdef CORE_3
976
977module dtlb_rd_c3 (
978
979 mytg
980);
981
982`include "tlb_sync.vh"
983
984input mytg;
985`ifndef GATESIM
986
987wire rd_vld;
988wire rd_vld_b;
989reg rd_vld_w;
990reg rd_vld_w2;
991reg rd_vld_w3;
992reg [(`TS_WIDTH-1):0] tstamp;
993
994wire [3:0] select_pc_b;
995reg [3:0] select_pc_w;
996reg [3:0] select_pc_w2;
997reg [3:0] select_pc_w3;
998wire [47:0] pc_b;
999reg [47:0] pc_w;
1000reg [47:0] pc_w2;
1001reg [47:0] pc_w3;
1002
1003wire irf_error_m;
1004wire irf_error_b;
1005reg irf_error_b_pre;
1006
1007reg [2:0] mycid;
1008reg [2:0] mytid;
1009reg [5:0] mytnum;
1010reg ready;
1011
1012reg [2:0] bsktid;
1013reg [5:0] bsktnum;
1014
1015integer i;
1016integer junk;
1017wire lsuErrorInB;
1018
1019reg [7:0] dtlbReadActive;
1020wire [7:0] blockStoreKill;
1021
1022wire [2:0] myLateErrTid = `SPC3.lsu_dcerr_tid_g[2:0];
1023wire [5:0] myLateErrTnum = (mycid * 8) + myLateErrTid;
1024
1025initial begin // {
1026 ready = 0;
1027 dtlbReadActive = 8'h0;
1028
1029 @(posedge `SPC3.l2clk) ;
1030 @(posedge `SPC3.l2clk) ;
1031 ready = `PARGS.tlb_sync_on;
1032 mycid = 3;
1033end //}
1034
1035//----------------------------------------------------------
1036// DUT probes
1037
1038
1039// I use this signal to get several standard errors in LSU that can happen
1040// that will cause a DTLB_READ, and use them to make sure they are not
1041// happening with perfom trap in the rd_vld_b signal
1042assign lsuErrorB = (`SPC3.lsu.dcc.lsu_align_b |
1043 `SPC3.lsu.dcc.lsu_lddf_align_b |
1044 `SPC3.lsu.dcc.lsu_stdf_align_b |
1045 `SPC3.lsu.dcc.lsu_dae_invalid_asi_b |
1046 `SPC3.lsu.dcc.lsu_dae_nc_page_b |
1047 `SPC3.lsu.dcc.lsu_dae_nfo_page_b |
1048 `SPC3.lsu.dcc.lsu_dae_priv_viol_b |
1049 `SPC3.lsu.dcc.lsu_dae_so_page |
1050 `SPC3.lsu.dcc.lsu_priv_action_b |
1051 `SPC3.lsu.dcc.lsu_va_watchpoint_b |
1052 `SPC3.lsu.dcc.lsu_pa_watchpoint_b |
1053 `SPC3.lsu.dcc.lsu_daccess_prot_b |
1054 `SPC3.lsu.dcc.lsu_dttp_err_b |
1055 `SPC3.lsu.dcc.lsu_dtdp_err_b |
1056 `SPC3.lsu.dcc.lsu_dtmh_err_b);
1057
1058
1059// Per tlb_sync spec, high priority (0-9) exceptions should not send DTLBREAD.
1060// tlu_flush_lsu_b - suppress DTLBREAD for high priority (0-9) exceptions.
1061// However, VA_watchpoint (TT=0x62, priority 11) also causes tlu_flush_lsu_b to be asserted.
1062// va_watchpoint_w_in was added to allow DTLBREAD to be sent even though tlu_flush_lsu_b fires.
1063// fgu_error_b - suppress DTLBREAD on FRF errors.
1064// irf_error_b - suppress DTLBREAD on IRF errors.
1065
1066assign select_pc_b = mytg ? `PROBES3.select_pc_b[7:4] : `PROBES3.select_pc_b[3:0];
1067assign rd_vld_b = mytg ?
1068
1069 (`PROBES3.tlb_rd_vld_b &&
1070 !`PROBES3.tlb_bypass_b &&
1071 !`SPC3.lsu.lsu_illegal_inst_b &&
1072 !`SPC3.lsu.dcc.fgu_error_b &&
1073 !irf_error_b &&
1074 !(`SPC3.lsu_perfmon_trap_b & `SPC3.tlu.fls1.pil_mask_15_b & ~lsuErrorB) &&
1075 !`SPC3.lsu.dcc.pipe_flush_b &&
1076 (!`SPC3.tlu_flush_lsu_b | `SPC3.tlu.fls1.va_watchpoint_w_in) &&
1077 `SPC3.tlu.fls1.lsu_inst_b &&
1078 (|select_pc_b)) :
1079
1080 (`PROBES3.tlb_rd_vld_b &&
1081 !`PROBES3.tlb_bypass_b &&
1082 !`SPC3.lsu.lsu_illegal_inst_b &&
1083 !`SPC3.lsu.dcc.fgu_error_b &&
1084 !irf_error_b &&
1085 !(`SPC3.lsu_perfmon_trap_b & `SPC3.tlu.fls0.pil_mask_15_b & ~lsuErrorB) &&
1086 !`SPC3.lsu.dcc.pipe_flush_b &&
1087 (!`SPC3.tlu_flush_lsu_b | `SPC3.tlu.fls0.va_watchpoint_w_in) &&
1088 `SPC3.tlu.fls0.lsu_inst_b &&
1089 (|select_pc_b));
1090
1091
1092assign blockStoreKill = {`SPC3.lsu.sbs7.bst_kill,
1093 `SPC3.lsu.sbs6.bst_kill,
1094 `SPC3.lsu.sbs5.bst_kill,
1095 `SPC3.lsu.sbs4.bst_kill,
1096 `SPC3.lsu.sbs3.bst_kill,
1097 `SPC3.lsu.sbs2.bst_kill,
1098 `SPC3.lsu.sbs1.bst_kill,
1099 `SPC3.lsu.sbs0.bst_kill};
1100
1101
1102
1103
1104
1105
1106// suppress DTLBREAD on STB errors.
1107assign rd_vld = rd_vld_w3 &&
1108 !(`SPC3.lsu.lmc.sbdlc_err | `SPC3.lsu.lmc.sbdlu_err);
1109
1110// suppress DTLBREAD on IRF errors
1111assign irf_error_m = (`SPC3.lsu.dcc.tid_m[2] ? `SPC3.exu_ecc_m[1] : `SPC3.exu_ecc_m[0]);
1112assign irf_error_b = irf_error_b_pre |
1113 ((`SPC3.lsu.dcc.tid_b[2] ? `SPC3.lsu.dcc.exu_ecc_m[1] :
1114 `SPC3.lsu.dcc.exu_ecc_m[0]) &
1115 `SPC3.lsu.dcc.twocycle_b &
1116
1117 ~(`SPC3.lsu.dcc.lsu_align_b |
1118 `SPC3.lsu.dcc.lsu_lddf_align_b |
1119 `SPC3.lsu.dcc.lsu_stdf_align_b |
1120 `SPC3.lsu.dcc.lsu_dae_invalid_asi_b |
1121 `SPC3.lsu.dcc.lsu_dae_nc_page_b |
1122 `SPC3.lsu.dcc.lsu_dae_nfo_page_b |
1123 `SPC3.lsu.dcc.lsu_dae_priv_viol_b |
1124 `SPC3.lsu.dcc.lsu_dae_so_page |
1125 `SPC3.lsu.dcc.lsu_priv_action_b |
1126 `SPC3.lsu.dcc.lsu_va_watchpoint_b |
1127 `SPC3.lsu.dcc.lsu_pa_watchpoint_b |
1128 ~`SPC3.lsu.dcc.lsu_tlb_miss_b_ |
1129 `SPC3.lsu.dcc.lsu_daccess_prot_b |
1130 `SPC3.lsu.dcc.lsu_dttp_err_b |
1131 `SPC3.lsu.dcc.lsu_dtdp_err_b |
1132 `SPC3.lsu.dcc.lsu_dtmh_err_b));
1133
1134
1135
1136assign pc_b = mytg ? `PROBES3.pc_1_b :
1137 `PROBES3.pc_0_b;
1138
1139//----------------------------------------------------------
1140// Send Command to NAS
1141
1142always @ (posedge `SPC3.l2clk & ready) begin // {
1143
1144 // if POR|WMR, then no TLBread
1145 if (`TOP.in_reset_core) begin // {
1146
1147 // flush pipeline during reset
1148 irf_error_b_pre <= 0;
1149
1150 rd_vld_w <= 0;
1151 rd_vld_w2 <= 0;
1152 rd_vld_w3 <= 0;
1153
1154 select_pc_w <= 0;
1155 select_pc_w2 <= 0;
1156 select_pc_w3 <= 0;
1157
1158 pc_w <= 0;
1159 pc_w2 <= 0;
1160 pc_w3 <= 0;
1161
1162 end // }
1163 else begin // {
1164
1165 tstamp = `TOP.core_cycle_cnt;
1166
1167 irf_error_b_pre <= irf_error_m;
1168
1169 rd_vld_w <= rd_vld_b;
1170 rd_vld_w2 <= rd_vld_w;
1171 rd_vld_w3 <= rd_vld_w2;
1172
1173 select_pc_w <= select_pc_b;
1174 select_pc_w2 <= select_pc_w;
1175 select_pc_w3 <= select_pc_w2;
1176
1177 pc_w <= pc_b;
1178 pc_w2 <= pc_w;
1179 pc_w3 <= pc_w2;
1180
1181 //---------------------------------
1182 if (rd_vld) begin // {
1183
1184 // Determine which thread is active
1185 for (i=0; i<=3; i=i+1) begin // {
1186 if (select_pc_w3[i]==1'b1) begin // {
1187 mytid = i + (mytg*4);
1188 mytnum = (mycid * 8) + mytid;
1189 end // }
1190 end // }
1191
1192
1193 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1194 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD tid=%d pc=%h ts=%0d",
1195 mycid,mytid,mytnum,pc_w3,tstamp-5);
1196 junk = $sim_send(`PLI_DTLBREAD, mytnum, tstamp-5);
1197
1198 //--------------------
1199 if (`PARGS.show_tlb_on) begin // {
1200 $display ("SHOW_TLB: DTLB_READ C%0d T%0d pc=%h ts=%0d",
1201 mycid,mytid,pc_w3,(tstamp-5)*`TOP.core_period);
1202 end //}
1203
1204 end //}
1205
1206 end // }
1207 end // in_reset}
1208
1209end // always }
1210
1211
1212//---------------------------------------------------------
1213// DTLB POP state machine
1214
1215always @ (posedge `SPC3.l2clk & ready) begin // {
1216
1217 // if POR|WMR, then no TLBread
1218 if (!`TOP.in_reset_core) begin // {
1219
1220 //Set read active when there is a valid lookup
1221 if (rd_vld_b) begin // {
1222 dtlbReadActive[`SPC3.lsu.dcc.tid_b[2:0]] <= 1'h1;
1223 end //}
1224
1225 //Clear it when there is a bypass
1226 if ((`SPC3.lsu.dcc.ld_inst_vld_b |
1227 `SPC3.lsu.dcc.st_inst_vld_b) &
1228 `SPC3.lsu.dcc.tlb_bypass_b &
1229 ~`SPC3.lsu.dcc.flush_all_b) begin // {
1230 dtlbReadActive[`SPC3.lsu.dcc.tid_b[2:0]] <= 1'h0;
1231 end //}
1232
1233 //Do a pop if we are active and then see a Perf Mon
1234 if ((`SPC3.lsu_perfmon_trap_g |
1235 `SPC3.lsu_dcl2u_err_g |
1236 `SPC3.lsu_dcl2nd_err_g) &
1237 dtlbReadActive[`SPC3.lsu_dcerr_tid_g[2:0]]) begin // {
1238 dtlbReadActive[`SPC3.lsu_dcerr_tid_g[2:0]] = 1'h0;
1239
1240 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1241 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
1242 mycid,myLateErrTid,myLateErrTnum,tstamp);
1243 junk = $sim_send(`PLI_DTLBREAD_POP, myLateErrTnum, tstamp);
1244
1245 //--------------------
1246 if (`PARGS.show_tlb_on) begin // {
1247 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
1248 mycid,mytid,tstamp*`TOP.core_period);
1249 end //}
1250 end //}
1251 end //}
1252
1253 // Determine which thread is active
1254 for (i=0; i<=3; i=i+1) begin // {
1255 bsktid = i + (mytg*4);
1256 bsktnum = (mycid * 8) + bsktid;
1257
1258 //Do a pop if we see a block storke kill
1259 if (blockStoreKill[bsktid] &
1260 dtlbReadActive[bsktid]) begin // {
1261 dtlbReadActive[bsktid] = 1'h0;
1262
1263 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1264 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
1265 mycid,bsktid,bsktnum,tstamp);
1266 junk = $sim_send(`PLI_DTLBREAD_POP, bsktnum, tstamp);
1267
1268 //--------------------
1269 if (`PARGS.show_tlb_on) begin // {
1270 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
1271 mycid,bsktid,tstamp*`TOP.core_period);
1272 end //}
1273 end // }
1274 end // }
1275
1276 end // for }
1277
1278 end // in_reset}
1279end // always}
1280
1281
1282
1283//----------------------------------------------------------
1284`endif
1285endmodule
1286
1287`endif
1288`ifdef CORE_4
1289
1290module dtlb_rd_c4 (
1291
1292 mytg
1293);
1294
1295`include "tlb_sync.vh"
1296
1297input mytg;
1298`ifndef GATESIM
1299
1300wire rd_vld;
1301wire rd_vld_b;
1302reg rd_vld_w;
1303reg rd_vld_w2;
1304reg rd_vld_w3;
1305reg [(`TS_WIDTH-1):0] tstamp;
1306
1307wire [3:0] select_pc_b;
1308reg [3:0] select_pc_w;
1309reg [3:0] select_pc_w2;
1310reg [3:0] select_pc_w3;
1311wire [47:0] pc_b;
1312reg [47:0] pc_w;
1313reg [47:0] pc_w2;
1314reg [47:0] pc_w3;
1315
1316wire irf_error_m;
1317wire irf_error_b;
1318reg irf_error_b_pre;
1319
1320reg [2:0] mycid;
1321reg [2:0] mytid;
1322reg [5:0] mytnum;
1323reg ready;
1324
1325reg [2:0] bsktid;
1326reg [5:0] bsktnum;
1327
1328integer i;
1329integer junk;
1330wire lsuErrorInB;
1331
1332reg [7:0] dtlbReadActive;
1333wire [7:0] blockStoreKill;
1334
1335wire [2:0] myLateErrTid = `SPC4.lsu_dcerr_tid_g[2:0];
1336wire [5:0] myLateErrTnum = (mycid * 8) + myLateErrTid;
1337
1338initial begin // {
1339 ready = 0;
1340 dtlbReadActive = 8'h0;
1341
1342 @(posedge `SPC4.l2clk) ;
1343 @(posedge `SPC4.l2clk) ;
1344 ready = `PARGS.tlb_sync_on;
1345 mycid = 4;
1346end //}
1347
1348//----------------------------------------------------------
1349// DUT probes
1350
1351
1352// I use this signal to get several standard errors in LSU that can happen
1353// that will cause a DTLB_READ, and use them to make sure they are not
1354// happening with perfom trap in the rd_vld_b signal
1355assign lsuErrorB = (`SPC4.lsu.dcc.lsu_align_b |
1356 `SPC4.lsu.dcc.lsu_lddf_align_b |
1357 `SPC4.lsu.dcc.lsu_stdf_align_b |
1358 `SPC4.lsu.dcc.lsu_dae_invalid_asi_b |
1359 `SPC4.lsu.dcc.lsu_dae_nc_page_b |
1360 `SPC4.lsu.dcc.lsu_dae_nfo_page_b |
1361 `SPC4.lsu.dcc.lsu_dae_priv_viol_b |
1362 `SPC4.lsu.dcc.lsu_dae_so_page |
1363 `SPC4.lsu.dcc.lsu_priv_action_b |
1364 `SPC4.lsu.dcc.lsu_va_watchpoint_b |
1365 `SPC4.lsu.dcc.lsu_pa_watchpoint_b |
1366 `SPC4.lsu.dcc.lsu_daccess_prot_b |
1367 `SPC4.lsu.dcc.lsu_dttp_err_b |
1368 `SPC4.lsu.dcc.lsu_dtdp_err_b |
1369 `SPC4.lsu.dcc.lsu_dtmh_err_b);
1370
1371
1372// Per tlb_sync spec, high priority (0-9) exceptions should not send DTLBREAD.
1373// tlu_flush_lsu_b - suppress DTLBREAD for high priority (0-9) exceptions.
1374// However, VA_watchpoint (TT=0x62, priority 11) also causes tlu_flush_lsu_b to be asserted.
1375// va_watchpoint_w_in was added to allow DTLBREAD to be sent even though tlu_flush_lsu_b fires.
1376// fgu_error_b - suppress DTLBREAD on FRF errors.
1377// irf_error_b - suppress DTLBREAD on IRF errors.
1378
1379assign select_pc_b = mytg ? `PROBES4.select_pc_b[7:4] : `PROBES4.select_pc_b[3:0];
1380assign rd_vld_b = mytg ?
1381
1382 (`PROBES4.tlb_rd_vld_b &&
1383 !`PROBES4.tlb_bypass_b &&
1384 !`SPC4.lsu.lsu_illegal_inst_b &&
1385 !`SPC4.lsu.dcc.fgu_error_b &&
1386 !irf_error_b &&
1387 !(`SPC4.lsu_perfmon_trap_b & `SPC4.tlu.fls1.pil_mask_15_b & ~lsuErrorB) &&
1388 !`SPC4.lsu.dcc.pipe_flush_b &&
1389 (!`SPC4.tlu_flush_lsu_b | `SPC4.tlu.fls1.va_watchpoint_w_in) &&
1390 `SPC4.tlu.fls1.lsu_inst_b &&
1391 (|select_pc_b)) :
1392
1393 (`PROBES4.tlb_rd_vld_b &&
1394 !`PROBES4.tlb_bypass_b &&
1395 !`SPC4.lsu.lsu_illegal_inst_b &&
1396 !`SPC4.lsu.dcc.fgu_error_b &&
1397 !irf_error_b &&
1398 !(`SPC4.lsu_perfmon_trap_b & `SPC4.tlu.fls0.pil_mask_15_b & ~lsuErrorB) &&
1399 !`SPC4.lsu.dcc.pipe_flush_b &&
1400 (!`SPC4.tlu_flush_lsu_b | `SPC4.tlu.fls0.va_watchpoint_w_in) &&
1401 `SPC4.tlu.fls0.lsu_inst_b &&
1402 (|select_pc_b));
1403
1404
1405assign blockStoreKill = {`SPC4.lsu.sbs7.bst_kill,
1406 `SPC4.lsu.sbs6.bst_kill,
1407 `SPC4.lsu.sbs5.bst_kill,
1408 `SPC4.lsu.sbs4.bst_kill,
1409 `SPC4.lsu.sbs3.bst_kill,
1410 `SPC4.lsu.sbs2.bst_kill,
1411 `SPC4.lsu.sbs1.bst_kill,
1412 `SPC4.lsu.sbs0.bst_kill};
1413
1414
1415
1416
1417
1418
1419// suppress DTLBREAD on STB errors.
1420assign rd_vld = rd_vld_w3 &&
1421 !(`SPC4.lsu.lmc.sbdlc_err | `SPC4.lsu.lmc.sbdlu_err);
1422
1423// suppress DTLBREAD on IRF errors
1424assign irf_error_m = (`SPC4.lsu.dcc.tid_m[2] ? `SPC4.exu_ecc_m[1] : `SPC4.exu_ecc_m[0]);
1425assign irf_error_b = irf_error_b_pre |
1426 ((`SPC4.lsu.dcc.tid_b[2] ? `SPC4.lsu.dcc.exu_ecc_m[1] :
1427 `SPC4.lsu.dcc.exu_ecc_m[0]) &
1428 `SPC4.lsu.dcc.twocycle_b &
1429
1430 ~(`SPC4.lsu.dcc.lsu_align_b |
1431 `SPC4.lsu.dcc.lsu_lddf_align_b |
1432 `SPC4.lsu.dcc.lsu_stdf_align_b |
1433 `SPC4.lsu.dcc.lsu_dae_invalid_asi_b |
1434 `SPC4.lsu.dcc.lsu_dae_nc_page_b |
1435 `SPC4.lsu.dcc.lsu_dae_nfo_page_b |
1436 `SPC4.lsu.dcc.lsu_dae_priv_viol_b |
1437 `SPC4.lsu.dcc.lsu_dae_so_page |
1438 `SPC4.lsu.dcc.lsu_priv_action_b |
1439 `SPC4.lsu.dcc.lsu_va_watchpoint_b |
1440 `SPC4.lsu.dcc.lsu_pa_watchpoint_b |
1441 ~`SPC4.lsu.dcc.lsu_tlb_miss_b_ |
1442 `SPC4.lsu.dcc.lsu_daccess_prot_b |
1443 `SPC4.lsu.dcc.lsu_dttp_err_b |
1444 `SPC4.lsu.dcc.lsu_dtdp_err_b |
1445 `SPC4.lsu.dcc.lsu_dtmh_err_b));
1446
1447
1448
1449assign pc_b = mytg ? `PROBES4.pc_1_b :
1450 `PROBES4.pc_0_b;
1451
1452//----------------------------------------------------------
1453// Send Command to NAS
1454
1455always @ (posedge `SPC4.l2clk & ready) begin // {
1456
1457 // if POR|WMR, then no TLBread
1458 if (`TOP.in_reset_core) begin // {
1459
1460 // flush pipeline during reset
1461 irf_error_b_pre <= 0;
1462
1463 rd_vld_w <= 0;
1464 rd_vld_w2 <= 0;
1465 rd_vld_w3 <= 0;
1466
1467 select_pc_w <= 0;
1468 select_pc_w2 <= 0;
1469 select_pc_w3 <= 0;
1470
1471 pc_w <= 0;
1472 pc_w2 <= 0;
1473 pc_w3 <= 0;
1474
1475 end // }
1476 else begin // {
1477
1478 tstamp = `TOP.core_cycle_cnt;
1479
1480 irf_error_b_pre <= irf_error_m;
1481
1482 rd_vld_w <= rd_vld_b;
1483 rd_vld_w2 <= rd_vld_w;
1484 rd_vld_w3 <= rd_vld_w2;
1485
1486 select_pc_w <= select_pc_b;
1487 select_pc_w2 <= select_pc_w;
1488 select_pc_w3 <= select_pc_w2;
1489
1490 pc_w <= pc_b;
1491 pc_w2 <= pc_w;
1492 pc_w3 <= pc_w2;
1493
1494 //---------------------------------
1495 if (rd_vld) begin // {
1496
1497 // Determine which thread is active
1498 for (i=0; i<=3; i=i+1) begin // {
1499 if (select_pc_w3[i]==1'b1) begin // {
1500 mytid = i + (mytg*4);
1501 mytnum = (mycid * 8) + mytid;
1502 end // }
1503 end // }
1504
1505
1506 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1507 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD tid=%d pc=%h ts=%0d",
1508 mycid,mytid,mytnum,pc_w3,tstamp-5);
1509 junk = $sim_send(`PLI_DTLBREAD, mytnum, tstamp-5);
1510
1511 //--------------------
1512 if (`PARGS.show_tlb_on) begin // {
1513 $display ("SHOW_TLB: DTLB_READ C%0d T%0d pc=%h ts=%0d",
1514 mycid,mytid,pc_w3,(tstamp-5)*`TOP.core_period);
1515 end //}
1516
1517 end //}
1518
1519 end // }
1520 end // in_reset}
1521
1522end // always }
1523
1524
1525//---------------------------------------------------------
1526// DTLB POP state machine
1527
1528always @ (posedge `SPC4.l2clk & ready) begin // {
1529
1530 // if POR|WMR, then no TLBread
1531 if (!`TOP.in_reset_core) begin // {
1532
1533 //Set read active when there is a valid lookup
1534 if (rd_vld_b) begin // {
1535 dtlbReadActive[`SPC4.lsu.dcc.tid_b[2:0]] <= 1'h1;
1536 end //}
1537
1538 //Clear it when there is a bypass
1539 if ((`SPC4.lsu.dcc.ld_inst_vld_b |
1540 `SPC4.lsu.dcc.st_inst_vld_b) &
1541 `SPC4.lsu.dcc.tlb_bypass_b &
1542 ~`SPC4.lsu.dcc.flush_all_b) begin // {
1543 dtlbReadActive[`SPC4.lsu.dcc.tid_b[2:0]] <= 1'h0;
1544 end //}
1545
1546 //Do a pop if we are active and then see a Perf Mon
1547 if ((`SPC4.lsu_perfmon_trap_g |
1548 `SPC4.lsu_dcl2u_err_g |
1549 `SPC4.lsu_dcl2nd_err_g) &
1550 dtlbReadActive[`SPC4.lsu_dcerr_tid_g[2:0]]) begin // {
1551 dtlbReadActive[`SPC4.lsu_dcerr_tid_g[2:0]] = 1'h0;
1552
1553 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1554 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
1555 mycid,myLateErrTid,myLateErrTnum,tstamp);
1556 junk = $sim_send(`PLI_DTLBREAD_POP, myLateErrTnum, tstamp);
1557
1558 //--------------------
1559 if (`PARGS.show_tlb_on) begin // {
1560 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
1561 mycid,mytid,tstamp*`TOP.core_period);
1562 end //}
1563 end //}
1564 end //}
1565
1566 // Determine which thread is active
1567 for (i=0; i<=3; i=i+1) begin // {
1568 bsktid = i + (mytg*4);
1569 bsktnum = (mycid * 8) + bsktid;
1570
1571 //Do a pop if we see a block storke kill
1572 if (blockStoreKill[bsktid] &
1573 dtlbReadActive[bsktid]) begin // {
1574 dtlbReadActive[bsktid] = 1'h0;
1575
1576 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1577 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
1578 mycid,bsktid,bsktnum,tstamp);
1579 junk = $sim_send(`PLI_DTLBREAD_POP, bsktnum, tstamp);
1580
1581 //--------------------
1582 if (`PARGS.show_tlb_on) begin // {
1583 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
1584 mycid,bsktid,tstamp*`TOP.core_period);
1585 end //}
1586 end // }
1587 end // }
1588
1589 end // for }
1590
1591 end // in_reset}
1592end // always}
1593
1594
1595
1596//----------------------------------------------------------
1597`endif
1598endmodule
1599
1600`endif
1601`ifdef CORE_5
1602
1603module dtlb_rd_c5 (
1604
1605 mytg
1606);
1607
1608`include "tlb_sync.vh"
1609
1610input mytg;
1611`ifndef GATESIM
1612
1613wire rd_vld;
1614wire rd_vld_b;
1615reg rd_vld_w;
1616reg rd_vld_w2;
1617reg rd_vld_w3;
1618reg [(`TS_WIDTH-1):0] tstamp;
1619
1620wire [3:0] select_pc_b;
1621reg [3:0] select_pc_w;
1622reg [3:0] select_pc_w2;
1623reg [3:0] select_pc_w3;
1624wire [47:0] pc_b;
1625reg [47:0] pc_w;
1626reg [47:0] pc_w2;
1627reg [47:0] pc_w3;
1628
1629wire irf_error_m;
1630wire irf_error_b;
1631reg irf_error_b_pre;
1632
1633reg [2:0] mycid;
1634reg [2:0] mytid;
1635reg [5:0] mytnum;
1636reg ready;
1637
1638reg [2:0] bsktid;
1639reg [5:0] bsktnum;
1640
1641integer i;
1642integer junk;
1643wire lsuErrorInB;
1644
1645reg [7:0] dtlbReadActive;
1646wire [7:0] blockStoreKill;
1647
1648wire [2:0] myLateErrTid = `SPC5.lsu_dcerr_tid_g[2:0];
1649wire [5:0] myLateErrTnum = (mycid * 8) + myLateErrTid;
1650
1651initial begin // {
1652 ready = 0;
1653 dtlbReadActive = 8'h0;
1654
1655 @(posedge `SPC5.l2clk) ;
1656 @(posedge `SPC5.l2clk) ;
1657 ready = `PARGS.tlb_sync_on;
1658 mycid = 5;
1659end //}
1660
1661//----------------------------------------------------------
1662// DUT probes
1663
1664
1665// I use this signal to get several standard errors in LSU that can happen
1666// that will cause a DTLB_READ, and use them to make sure they are not
1667// happening with perfom trap in the rd_vld_b signal
1668assign lsuErrorB = (`SPC5.lsu.dcc.lsu_align_b |
1669 `SPC5.lsu.dcc.lsu_lddf_align_b |
1670 `SPC5.lsu.dcc.lsu_stdf_align_b |
1671 `SPC5.lsu.dcc.lsu_dae_invalid_asi_b |
1672 `SPC5.lsu.dcc.lsu_dae_nc_page_b |
1673 `SPC5.lsu.dcc.lsu_dae_nfo_page_b |
1674 `SPC5.lsu.dcc.lsu_dae_priv_viol_b |
1675 `SPC5.lsu.dcc.lsu_dae_so_page |
1676 `SPC5.lsu.dcc.lsu_priv_action_b |
1677 `SPC5.lsu.dcc.lsu_va_watchpoint_b |
1678 `SPC5.lsu.dcc.lsu_pa_watchpoint_b |
1679 `SPC5.lsu.dcc.lsu_daccess_prot_b |
1680 `SPC5.lsu.dcc.lsu_dttp_err_b |
1681 `SPC5.lsu.dcc.lsu_dtdp_err_b |
1682 `SPC5.lsu.dcc.lsu_dtmh_err_b);
1683
1684
1685// Per tlb_sync spec, high priority (0-9) exceptions should not send DTLBREAD.
1686// tlu_flush_lsu_b - suppress DTLBREAD for high priority (0-9) exceptions.
1687// However, VA_watchpoint (TT=0x62, priority 11) also causes tlu_flush_lsu_b to be asserted.
1688// va_watchpoint_w_in was added to allow DTLBREAD to be sent even though tlu_flush_lsu_b fires.
1689// fgu_error_b - suppress DTLBREAD on FRF errors.
1690// irf_error_b - suppress DTLBREAD on IRF errors.
1691
1692assign select_pc_b = mytg ? `PROBES5.select_pc_b[7:4] : `PROBES5.select_pc_b[3:0];
1693assign rd_vld_b = mytg ?
1694
1695 (`PROBES5.tlb_rd_vld_b &&
1696 !`PROBES5.tlb_bypass_b &&
1697 !`SPC5.lsu.lsu_illegal_inst_b &&
1698 !`SPC5.lsu.dcc.fgu_error_b &&
1699 !irf_error_b &&
1700 !(`SPC5.lsu_perfmon_trap_b & `SPC5.tlu.fls1.pil_mask_15_b & ~lsuErrorB) &&
1701 !`SPC5.lsu.dcc.pipe_flush_b &&
1702 (!`SPC5.tlu_flush_lsu_b | `SPC5.tlu.fls1.va_watchpoint_w_in) &&
1703 `SPC5.tlu.fls1.lsu_inst_b &&
1704 (|select_pc_b)) :
1705
1706 (`PROBES5.tlb_rd_vld_b &&
1707 !`PROBES5.tlb_bypass_b &&
1708 !`SPC5.lsu.lsu_illegal_inst_b &&
1709 !`SPC5.lsu.dcc.fgu_error_b &&
1710 !irf_error_b &&
1711 !(`SPC5.lsu_perfmon_trap_b & `SPC5.tlu.fls0.pil_mask_15_b & ~lsuErrorB) &&
1712 !`SPC5.lsu.dcc.pipe_flush_b &&
1713 (!`SPC5.tlu_flush_lsu_b | `SPC5.tlu.fls0.va_watchpoint_w_in) &&
1714 `SPC5.tlu.fls0.lsu_inst_b &&
1715 (|select_pc_b));
1716
1717
1718assign blockStoreKill = {`SPC5.lsu.sbs7.bst_kill,
1719 `SPC5.lsu.sbs6.bst_kill,
1720 `SPC5.lsu.sbs5.bst_kill,
1721 `SPC5.lsu.sbs4.bst_kill,
1722 `SPC5.lsu.sbs3.bst_kill,
1723 `SPC5.lsu.sbs2.bst_kill,
1724 `SPC5.lsu.sbs1.bst_kill,
1725 `SPC5.lsu.sbs0.bst_kill};
1726
1727
1728
1729
1730
1731
1732// suppress DTLBREAD on STB errors.
1733assign rd_vld = rd_vld_w3 &&
1734 !(`SPC5.lsu.lmc.sbdlc_err | `SPC5.lsu.lmc.sbdlu_err);
1735
1736// suppress DTLBREAD on IRF errors
1737assign irf_error_m = (`SPC5.lsu.dcc.tid_m[2] ? `SPC5.exu_ecc_m[1] : `SPC5.exu_ecc_m[0]);
1738assign irf_error_b = irf_error_b_pre |
1739 ((`SPC5.lsu.dcc.tid_b[2] ? `SPC5.lsu.dcc.exu_ecc_m[1] :
1740 `SPC5.lsu.dcc.exu_ecc_m[0]) &
1741 `SPC5.lsu.dcc.twocycle_b &
1742
1743 ~(`SPC5.lsu.dcc.lsu_align_b |
1744 `SPC5.lsu.dcc.lsu_lddf_align_b |
1745 `SPC5.lsu.dcc.lsu_stdf_align_b |
1746 `SPC5.lsu.dcc.lsu_dae_invalid_asi_b |
1747 `SPC5.lsu.dcc.lsu_dae_nc_page_b |
1748 `SPC5.lsu.dcc.lsu_dae_nfo_page_b |
1749 `SPC5.lsu.dcc.lsu_dae_priv_viol_b |
1750 `SPC5.lsu.dcc.lsu_dae_so_page |
1751 `SPC5.lsu.dcc.lsu_priv_action_b |
1752 `SPC5.lsu.dcc.lsu_va_watchpoint_b |
1753 `SPC5.lsu.dcc.lsu_pa_watchpoint_b |
1754 ~`SPC5.lsu.dcc.lsu_tlb_miss_b_ |
1755 `SPC5.lsu.dcc.lsu_daccess_prot_b |
1756 `SPC5.lsu.dcc.lsu_dttp_err_b |
1757 `SPC5.lsu.dcc.lsu_dtdp_err_b |
1758 `SPC5.lsu.dcc.lsu_dtmh_err_b));
1759
1760
1761
1762assign pc_b = mytg ? `PROBES5.pc_1_b :
1763 `PROBES5.pc_0_b;
1764
1765//----------------------------------------------------------
1766// Send Command to NAS
1767
1768always @ (posedge `SPC5.l2clk & ready) begin // {
1769
1770 // if POR|WMR, then no TLBread
1771 if (`TOP.in_reset_core) begin // {
1772
1773 // flush pipeline during reset
1774 irf_error_b_pre <= 0;
1775
1776 rd_vld_w <= 0;
1777 rd_vld_w2 <= 0;
1778 rd_vld_w3 <= 0;
1779
1780 select_pc_w <= 0;
1781 select_pc_w2 <= 0;
1782 select_pc_w3 <= 0;
1783
1784 pc_w <= 0;
1785 pc_w2 <= 0;
1786 pc_w3 <= 0;
1787
1788 end // }
1789 else begin // {
1790
1791 tstamp = `TOP.core_cycle_cnt;
1792
1793 irf_error_b_pre <= irf_error_m;
1794
1795 rd_vld_w <= rd_vld_b;
1796 rd_vld_w2 <= rd_vld_w;
1797 rd_vld_w3 <= rd_vld_w2;
1798
1799 select_pc_w <= select_pc_b;
1800 select_pc_w2 <= select_pc_w;
1801 select_pc_w3 <= select_pc_w2;
1802
1803 pc_w <= pc_b;
1804 pc_w2 <= pc_w;
1805 pc_w3 <= pc_w2;
1806
1807 //---------------------------------
1808 if (rd_vld) begin // {
1809
1810 // Determine which thread is active
1811 for (i=0; i<=3; i=i+1) begin // {
1812 if (select_pc_w3[i]==1'b1) begin // {
1813 mytid = i + (mytg*4);
1814 mytnum = (mycid * 8) + mytid;
1815 end // }
1816 end // }
1817
1818
1819 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1820 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD tid=%d pc=%h ts=%0d",
1821 mycid,mytid,mytnum,pc_w3,tstamp-5);
1822 junk = $sim_send(`PLI_DTLBREAD, mytnum, tstamp-5);
1823
1824 //--------------------
1825 if (`PARGS.show_tlb_on) begin // {
1826 $display ("SHOW_TLB: DTLB_READ C%0d T%0d pc=%h ts=%0d",
1827 mycid,mytid,pc_w3,(tstamp-5)*`TOP.core_period);
1828 end //}
1829
1830 end //}
1831
1832 end // }
1833 end // in_reset}
1834
1835end // always }
1836
1837
1838//---------------------------------------------------------
1839// DTLB POP state machine
1840
1841always @ (posedge `SPC5.l2clk & ready) begin // {
1842
1843 // if POR|WMR, then no TLBread
1844 if (!`TOP.in_reset_core) begin // {
1845
1846 //Set read active when there is a valid lookup
1847 if (rd_vld_b) begin // {
1848 dtlbReadActive[`SPC5.lsu.dcc.tid_b[2:0]] <= 1'h1;
1849 end //}
1850
1851 //Clear it when there is a bypass
1852 if ((`SPC5.lsu.dcc.ld_inst_vld_b |
1853 `SPC5.lsu.dcc.st_inst_vld_b) &
1854 `SPC5.lsu.dcc.tlb_bypass_b &
1855 ~`SPC5.lsu.dcc.flush_all_b) begin // {
1856 dtlbReadActive[`SPC5.lsu.dcc.tid_b[2:0]] <= 1'h0;
1857 end //}
1858
1859 //Do a pop if we are active and then see a Perf Mon
1860 if ((`SPC5.lsu_perfmon_trap_g |
1861 `SPC5.lsu_dcl2u_err_g |
1862 `SPC5.lsu_dcl2nd_err_g) &
1863 dtlbReadActive[`SPC5.lsu_dcerr_tid_g[2:0]]) begin // {
1864 dtlbReadActive[`SPC5.lsu_dcerr_tid_g[2:0]] = 1'h0;
1865
1866 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1867 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
1868 mycid,myLateErrTid,myLateErrTnum,tstamp);
1869 junk = $sim_send(`PLI_DTLBREAD_POP, myLateErrTnum, tstamp);
1870
1871 //--------------------
1872 if (`PARGS.show_tlb_on) begin // {
1873 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
1874 mycid,mytid,tstamp*`TOP.core_period);
1875 end //}
1876 end //}
1877 end //}
1878
1879 // Determine which thread is active
1880 for (i=0; i<=3; i=i+1) begin // {
1881 bsktid = i + (mytg*4);
1882 bsktnum = (mycid * 8) + bsktid;
1883
1884 //Do a pop if we see a block storke kill
1885 if (blockStoreKill[bsktid] &
1886 dtlbReadActive[bsktid]) begin // {
1887 dtlbReadActive[bsktid] = 1'h0;
1888
1889 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1890 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
1891 mycid,bsktid,bsktnum,tstamp);
1892 junk = $sim_send(`PLI_DTLBREAD_POP, bsktnum, tstamp);
1893
1894 //--------------------
1895 if (`PARGS.show_tlb_on) begin // {
1896 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
1897 mycid,bsktid,tstamp*`TOP.core_period);
1898 end //}
1899 end // }
1900 end // }
1901
1902 end // for }
1903
1904 end // in_reset}
1905end // always}
1906
1907
1908
1909//----------------------------------------------------------
1910`endif
1911endmodule
1912
1913`endif
1914`ifdef CORE_6
1915
1916module dtlb_rd_c6 (
1917
1918 mytg
1919);
1920
1921`include "tlb_sync.vh"
1922
1923input mytg;
1924`ifndef GATESIM
1925
1926wire rd_vld;
1927wire rd_vld_b;
1928reg rd_vld_w;
1929reg rd_vld_w2;
1930reg rd_vld_w3;
1931reg [(`TS_WIDTH-1):0] tstamp;
1932
1933wire [3:0] select_pc_b;
1934reg [3:0] select_pc_w;
1935reg [3:0] select_pc_w2;
1936reg [3:0] select_pc_w3;
1937wire [47:0] pc_b;
1938reg [47:0] pc_w;
1939reg [47:0] pc_w2;
1940reg [47:0] pc_w3;
1941
1942wire irf_error_m;
1943wire irf_error_b;
1944reg irf_error_b_pre;
1945
1946reg [2:0] mycid;
1947reg [2:0] mytid;
1948reg [5:0] mytnum;
1949reg ready;
1950
1951reg [2:0] bsktid;
1952reg [5:0] bsktnum;
1953
1954integer i;
1955integer junk;
1956wire lsuErrorInB;
1957
1958reg [7:0] dtlbReadActive;
1959wire [7:0] blockStoreKill;
1960
1961wire [2:0] myLateErrTid = `SPC6.lsu_dcerr_tid_g[2:0];
1962wire [5:0] myLateErrTnum = (mycid * 8) + myLateErrTid;
1963
1964initial begin // {
1965 ready = 0;
1966 dtlbReadActive = 8'h0;
1967
1968 @(posedge `SPC6.l2clk) ;
1969 @(posedge `SPC6.l2clk) ;
1970 ready = `PARGS.tlb_sync_on;
1971 mycid = 6;
1972end //}
1973
1974//----------------------------------------------------------
1975// DUT probes
1976
1977
1978// I use this signal to get several standard errors in LSU that can happen
1979// that will cause a DTLB_READ, and use them to make sure they are not
1980// happening with perfom trap in the rd_vld_b signal
1981assign lsuErrorB = (`SPC6.lsu.dcc.lsu_align_b |
1982 `SPC6.lsu.dcc.lsu_lddf_align_b |
1983 `SPC6.lsu.dcc.lsu_stdf_align_b |
1984 `SPC6.lsu.dcc.lsu_dae_invalid_asi_b |
1985 `SPC6.lsu.dcc.lsu_dae_nc_page_b |
1986 `SPC6.lsu.dcc.lsu_dae_nfo_page_b |
1987 `SPC6.lsu.dcc.lsu_dae_priv_viol_b |
1988 `SPC6.lsu.dcc.lsu_dae_so_page |
1989 `SPC6.lsu.dcc.lsu_priv_action_b |
1990 `SPC6.lsu.dcc.lsu_va_watchpoint_b |
1991 `SPC6.lsu.dcc.lsu_pa_watchpoint_b |
1992 `SPC6.lsu.dcc.lsu_daccess_prot_b |
1993 `SPC6.lsu.dcc.lsu_dttp_err_b |
1994 `SPC6.lsu.dcc.lsu_dtdp_err_b |
1995 `SPC6.lsu.dcc.lsu_dtmh_err_b);
1996
1997
1998// Per tlb_sync spec, high priority (0-9) exceptions should not send DTLBREAD.
1999// tlu_flush_lsu_b - suppress DTLBREAD for high priority (0-9) exceptions.
2000// However, VA_watchpoint (TT=0x62, priority 11) also causes tlu_flush_lsu_b to be asserted.
2001// va_watchpoint_w_in was added to allow DTLBREAD to be sent even though tlu_flush_lsu_b fires.
2002// fgu_error_b - suppress DTLBREAD on FRF errors.
2003// irf_error_b - suppress DTLBREAD on IRF errors.
2004
2005assign select_pc_b = mytg ? `PROBES6.select_pc_b[7:4] : `PROBES6.select_pc_b[3:0];
2006assign rd_vld_b = mytg ?
2007
2008 (`PROBES6.tlb_rd_vld_b &&
2009 !`PROBES6.tlb_bypass_b &&
2010 !`SPC6.lsu.lsu_illegal_inst_b &&
2011 !`SPC6.lsu.dcc.fgu_error_b &&
2012 !irf_error_b &&
2013 !(`SPC6.lsu_perfmon_trap_b & `SPC6.tlu.fls1.pil_mask_15_b & ~lsuErrorB) &&
2014 !`SPC6.lsu.dcc.pipe_flush_b &&
2015 (!`SPC6.tlu_flush_lsu_b | `SPC6.tlu.fls1.va_watchpoint_w_in) &&
2016 `SPC6.tlu.fls1.lsu_inst_b &&
2017 (|select_pc_b)) :
2018
2019 (`PROBES6.tlb_rd_vld_b &&
2020 !`PROBES6.tlb_bypass_b &&
2021 !`SPC6.lsu.lsu_illegal_inst_b &&
2022 !`SPC6.lsu.dcc.fgu_error_b &&
2023 !irf_error_b &&
2024 !(`SPC6.lsu_perfmon_trap_b & `SPC6.tlu.fls0.pil_mask_15_b & ~lsuErrorB) &&
2025 !`SPC6.lsu.dcc.pipe_flush_b &&
2026 (!`SPC6.tlu_flush_lsu_b | `SPC6.tlu.fls0.va_watchpoint_w_in) &&
2027 `SPC6.tlu.fls0.lsu_inst_b &&
2028 (|select_pc_b));
2029
2030
2031assign blockStoreKill = {`SPC6.lsu.sbs7.bst_kill,
2032 `SPC6.lsu.sbs6.bst_kill,
2033 `SPC6.lsu.sbs5.bst_kill,
2034 `SPC6.lsu.sbs4.bst_kill,
2035 `SPC6.lsu.sbs3.bst_kill,
2036 `SPC6.lsu.sbs2.bst_kill,
2037 `SPC6.lsu.sbs1.bst_kill,
2038 `SPC6.lsu.sbs0.bst_kill};
2039
2040
2041
2042
2043
2044
2045// suppress DTLBREAD on STB errors.
2046assign rd_vld = rd_vld_w3 &&
2047 !(`SPC6.lsu.lmc.sbdlc_err | `SPC6.lsu.lmc.sbdlu_err);
2048
2049// suppress DTLBREAD on IRF errors
2050assign irf_error_m = (`SPC6.lsu.dcc.tid_m[2] ? `SPC6.exu_ecc_m[1] : `SPC6.exu_ecc_m[0]);
2051assign irf_error_b = irf_error_b_pre |
2052 ((`SPC6.lsu.dcc.tid_b[2] ? `SPC6.lsu.dcc.exu_ecc_m[1] :
2053 `SPC6.lsu.dcc.exu_ecc_m[0]) &
2054 `SPC6.lsu.dcc.twocycle_b &
2055
2056 ~(`SPC6.lsu.dcc.lsu_align_b |
2057 `SPC6.lsu.dcc.lsu_lddf_align_b |
2058 `SPC6.lsu.dcc.lsu_stdf_align_b |
2059 `SPC6.lsu.dcc.lsu_dae_invalid_asi_b |
2060 `SPC6.lsu.dcc.lsu_dae_nc_page_b |
2061 `SPC6.lsu.dcc.lsu_dae_nfo_page_b |
2062 `SPC6.lsu.dcc.lsu_dae_priv_viol_b |
2063 `SPC6.lsu.dcc.lsu_dae_so_page |
2064 `SPC6.lsu.dcc.lsu_priv_action_b |
2065 `SPC6.lsu.dcc.lsu_va_watchpoint_b |
2066 `SPC6.lsu.dcc.lsu_pa_watchpoint_b |
2067 ~`SPC6.lsu.dcc.lsu_tlb_miss_b_ |
2068 `SPC6.lsu.dcc.lsu_daccess_prot_b |
2069 `SPC6.lsu.dcc.lsu_dttp_err_b |
2070 `SPC6.lsu.dcc.lsu_dtdp_err_b |
2071 `SPC6.lsu.dcc.lsu_dtmh_err_b));
2072
2073
2074
2075assign pc_b = mytg ? `PROBES6.pc_1_b :
2076 `PROBES6.pc_0_b;
2077
2078//----------------------------------------------------------
2079// Send Command to NAS
2080
2081always @ (posedge `SPC6.l2clk & ready) begin // {
2082
2083 // if POR|WMR, then no TLBread
2084 if (`TOP.in_reset_core) begin // {
2085
2086 // flush pipeline during reset
2087 irf_error_b_pre <= 0;
2088
2089 rd_vld_w <= 0;
2090 rd_vld_w2 <= 0;
2091 rd_vld_w3 <= 0;
2092
2093 select_pc_w <= 0;
2094 select_pc_w2 <= 0;
2095 select_pc_w3 <= 0;
2096
2097 pc_w <= 0;
2098 pc_w2 <= 0;
2099 pc_w3 <= 0;
2100
2101 end // }
2102 else begin // {
2103
2104 tstamp = `TOP.core_cycle_cnt;
2105
2106 irf_error_b_pre <= irf_error_m;
2107
2108 rd_vld_w <= rd_vld_b;
2109 rd_vld_w2 <= rd_vld_w;
2110 rd_vld_w3 <= rd_vld_w2;
2111
2112 select_pc_w <= select_pc_b;
2113 select_pc_w2 <= select_pc_w;
2114 select_pc_w3 <= select_pc_w2;
2115
2116 pc_w <= pc_b;
2117 pc_w2 <= pc_w;
2118 pc_w3 <= pc_w2;
2119
2120 //---------------------------------
2121 if (rd_vld) begin // {
2122
2123 // Determine which thread is active
2124 for (i=0; i<=3; i=i+1) begin // {
2125 if (select_pc_w3[i]==1'b1) begin // {
2126 mytid = i + (mytg*4);
2127 mytnum = (mycid * 8) + mytid;
2128 end // }
2129 end // }
2130
2131
2132 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2133 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD tid=%d pc=%h ts=%0d",
2134 mycid,mytid,mytnum,pc_w3,tstamp-5);
2135 junk = $sim_send(`PLI_DTLBREAD, mytnum, tstamp-5);
2136
2137 //--------------------
2138 if (`PARGS.show_tlb_on) begin // {
2139 $display ("SHOW_TLB: DTLB_READ C%0d T%0d pc=%h ts=%0d",
2140 mycid,mytid,pc_w3,(tstamp-5)*`TOP.core_period);
2141 end //}
2142
2143 end //}
2144
2145 end // }
2146 end // in_reset}
2147
2148end // always }
2149
2150
2151//---------------------------------------------------------
2152// DTLB POP state machine
2153
2154always @ (posedge `SPC6.l2clk & ready) begin // {
2155
2156 // if POR|WMR, then no TLBread
2157 if (!`TOP.in_reset_core) begin // {
2158
2159 //Set read active when there is a valid lookup
2160 if (rd_vld_b) begin // {
2161 dtlbReadActive[`SPC6.lsu.dcc.tid_b[2:0]] <= 1'h1;
2162 end //}
2163
2164 //Clear it when there is a bypass
2165 if ((`SPC6.lsu.dcc.ld_inst_vld_b |
2166 `SPC6.lsu.dcc.st_inst_vld_b) &
2167 `SPC6.lsu.dcc.tlb_bypass_b &
2168 ~`SPC6.lsu.dcc.flush_all_b) begin // {
2169 dtlbReadActive[`SPC6.lsu.dcc.tid_b[2:0]] <= 1'h0;
2170 end //}
2171
2172 //Do a pop if we are active and then see a Perf Mon
2173 if ((`SPC6.lsu_perfmon_trap_g |
2174 `SPC6.lsu_dcl2u_err_g |
2175 `SPC6.lsu_dcl2nd_err_g) &
2176 dtlbReadActive[`SPC6.lsu_dcerr_tid_g[2:0]]) begin // {
2177 dtlbReadActive[`SPC6.lsu_dcerr_tid_g[2:0]] = 1'h0;
2178
2179 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2180 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
2181 mycid,myLateErrTid,myLateErrTnum,tstamp);
2182 junk = $sim_send(`PLI_DTLBREAD_POP, myLateErrTnum, tstamp);
2183
2184 //--------------------
2185 if (`PARGS.show_tlb_on) begin // {
2186 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
2187 mycid,mytid,tstamp*`TOP.core_period);
2188 end //}
2189 end //}
2190 end //}
2191
2192 // Determine which thread is active
2193 for (i=0; i<=3; i=i+1) begin // {
2194 bsktid = i + (mytg*4);
2195 bsktnum = (mycid * 8) + bsktid;
2196
2197 //Do a pop if we see a block storke kill
2198 if (blockStoreKill[bsktid] &
2199 dtlbReadActive[bsktid]) begin // {
2200 dtlbReadActive[bsktid] = 1'h0;
2201
2202 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2203 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
2204 mycid,bsktid,bsktnum,tstamp);
2205 junk = $sim_send(`PLI_DTLBREAD_POP, bsktnum, tstamp);
2206
2207 //--------------------
2208 if (`PARGS.show_tlb_on) begin // {
2209 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
2210 mycid,bsktid,tstamp*`TOP.core_period);
2211 end //}
2212 end // }
2213 end // }
2214
2215 end // for }
2216
2217 end // in_reset}
2218end // always}
2219
2220
2221
2222//----------------------------------------------------------
2223`endif
2224endmodule
2225
2226`endif
2227`ifdef CORE_7
2228
2229module dtlb_rd_c7 (
2230
2231 mytg
2232);
2233
2234`include "tlb_sync.vh"
2235
2236input mytg;
2237`ifndef GATESIM
2238
2239wire rd_vld;
2240wire rd_vld_b;
2241reg rd_vld_w;
2242reg rd_vld_w2;
2243reg rd_vld_w3;
2244reg [(`TS_WIDTH-1):0] tstamp;
2245
2246wire [3:0] select_pc_b;
2247reg [3:0] select_pc_w;
2248reg [3:0] select_pc_w2;
2249reg [3:0] select_pc_w3;
2250wire [47:0] pc_b;
2251reg [47:0] pc_w;
2252reg [47:0] pc_w2;
2253reg [47:0] pc_w3;
2254
2255wire irf_error_m;
2256wire irf_error_b;
2257reg irf_error_b_pre;
2258
2259reg [2:0] mycid;
2260reg [2:0] mytid;
2261reg [5:0] mytnum;
2262reg ready;
2263
2264reg [2:0] bsktid;
2265reg [5:0] bsktnum;
2266
2267integer i;
2268integer junk;
2269wire lsuErrorInB;
2270
2271reg [7:0] dtlbReadActive;
2272wire [7:0] blockStoreKill;
2273
2274wire [2:0] myLateErrTid = `SPC7.lsu_dcerr_tid_g[2:0];
2275wire [5:0] myLateErrTnum = (mycid * 8) + myLateErrTid;
2276
2277initial begin // {
2278 ready = 0;
2279 dtlbReadActive = 8'h0;
2280
2281 @(posedge `SPC7.l2clk) ;
2282 @(posedge `SPC7.l2clk) ;
2283 ready = `PARGS.tlb_sync_on;
2284 mycid = 7;
2285end //}
2286
2287//----------------------------------------------------------
2288// DUT probes
2289
2290
2291// I use this signal to get several standard errors in LSU that can happen
2292// that will cause a DTLB_READ, and use them to make sure they are not
2293// happening with perfom trap in the rd_vld_b signal
2294assign lsuErrorB = (`SPC7.lsu.dcc.lsu_align_b |
2295 `SPC7.lsu.dcc.lsu_lddf_align_b |
2296 `SPC7.lsu.dcc.lsu_stdf_align_b |
2297 `SPC7.lsu.dcc.lsu_dae_invalid_asi_b |
2298 `SPC7.lsu.dcc.lsu_dae_nc_page_b |
2299 `SPC7.lsu.dcc.lsu_dae_nfo_page_b |
2300 `SPC7.lsu.dcc.lsu_dae_priv_viol_b |
2301 `SPC7.lsu.dcc.lsu_dae_so_page |
2302 `SPC7.lsu.dcc.lsu_priv_action_b |
2303 `SPC7.lsu.dcc.lsu_va_watchpoint_b |
2304 `SPC7.lsu.dcc.lsu_pa_watchpoint_b |
2305 `SPC7.lsu.dcc.lsu_daccess_prot_b |
2306 `SPC7.lsu.dcc.lsu_dttp_err_b |
2307 `SPC7.lsu.dcc.lsu_dtdp_err_b |
2308 `SPC7.lsu.dcc.lsu_dtmh_err_b);
2309
2310
2311// Per tlb_sync spec, high priority (0-9) exceptions should not send DTLBREAD.
2312// tlu_flush_lsu_b - suppress DTLBREAD for high priority (0-9) exceptions.
2313// However, VA_watchpoint (TT=0x62, priority 11) also causes tlu_flush_lsu_b to be asserted.
2314// va_watchpoint_w_in was added to allow DTLBREAD to be sent even though tlu_flush_lsu_b fires.
2315// fgu_error_b - suppress DTLBREAD on FRF errors.
2316// irf_error_b - suppress DTLBREAD on IRF errors.
2317
2318assign select_pc_b = mytg ? `PROBES7.select_pc_b[7:4] : `PROBES7.select_pc_b[3:0];
2319assign rd_vld_b = mytg ?
2320
2321 (`PROBES7.tlb_rd_vld_b &&
2322 !`PROBES7.tlb_bypass_b &&
2323 !`SPC7.lsu.lsu_illegal_inst_b &&
2324 !`SPC7.lsu.dcc.fgu_error_b &&
2325 !irf_error_b &&
2326 !(`SPC7.lsu_perfmon_trap_b & `SPC7.tlu.fls1.pil_mask_15_b & ~lsuErrorB) &&
2327 !`SPC7.lsu.dcc.pipe_flush_b &&
2328 (!`SPC7.tlu_flush_lsu_b | `SPC7.tlu.fls1.va_watchpoint_w_in) &&
2329 `SPC7.tlu.fls1.lsu_inst_b &&
2330 (|select_pc_b)) :
2331
2332 (`PROBES7.tlb_rd_vld_b &&
2333 !`PROBES7.tlb_bypass_b &&
2334 !`SPC7.lsu.lsu_illegal_inst_b &&
2335 !`SPC7.lsu.dcc.fgu_error_b &&
2336 !irf_error_b &&
2337 !(`SPC7.lsu_perfmon_trap_b & `SPC7.tlu.fls0.pil_mask_15_b & ~lsuErrorB) &&
2338 !`SPC7.lsu.dcc.pipe_flush_b &&
2339 (!`SPC7.tlu_flush_lsu_b | `SPC7.tlu.fls0.va_watchpoint_w_in) &&
2340 `SPC7.tlu.fls0.lsu_inst_b &&
2341 (|select_pc_b));
2342
2343
2344assign blockStoreKill = {`SPC7.lsu.sbs7.bst_kill,
2345 `SPC7.lsu.sbs6.bst_kill,
2346 `SPC7.lsu.sbs5.bst_kill,
2347 `SPC7.lsu.sbs4.bst_kill,
2348 `SPC7.lsu.sbs3.bst_kill,
2349 `SPC7.lsu.sbs2.bst_kill,
2350 `SPC7.lsu.sbs1.bst_kill,
2351 `SPC7.lsu.sbs0.bst_kill};
2352
2353
2354
2355
2356
2357
2358// suppress DTLBREAD on STB errors.
2359assign rd_vld = rd_vld_w3 &&
2360 !(`SPC7.lsu.lmc.sbdlc_err | `SPC7.lsu.lmc.sbdlu_err);
2361
2362// suppress DTLBREAD on IRF errors
2363assign irf_error_m = (`SPC7.lsu.dcc.tid_m[2] ? `SPC7.exu_ecc_m[1] : `SPC7.exu_ecc_m[0]);
2364assign irf_error_b = irf_error_b_pre |
2365 ((`SPC7.lsu.dcc.tid_b[2] ? `SPC7.lsu.dcc.exu_ecc_m[1] :
2366 `SPC7.lsu.dcc.exu_ecc_m[0]) &
2367 `SPC7.lsu.dcc.twocycle_b &
2368
2369 ~(`SPC7.lsu.dcc.lsu_align_b |
2370 `SPC7.lsu.dcc.lsu_lddf_align_b |
2371 `SPC7.lsu.dcc.lsu_stdf_align_b |
2372 `SPC7.lsu.dcc.lsu_dae_invalid_asi_b |
2373 `SPC7.lsu.dcc.lsu_dae_nc_page_b |
2374 `SPC7.lsu.dcc.lsu_dae_nfo_page_b |
2375 `SPC7.lsu.dcc.lsu_dae_priv_viol_b |
2376 `SPC7.lsu.dcc.lsu_dae_so_page |
2377 `SPC7.lsu.dcc.lsu_priv_action_b |
2378 `SPC7.lsu.dcc.lsu_va_watchpoint_b |
2379 `SPC7.lsu.dcc.lsu_pa_watchpoint_b |
2380 ~`SPC7.lsu.dcc.lsu_tlb_miss_b_ |
2381 `SPC7.lsu.dcc.lsu_daccess_prot_b |
2382 `SPC7.lsu.dcc.lsu_dttp_err_b |
2383 `SPC7.lsu.dcc.lsu_dtdp_err_b |
2384 `SPC7.lsu.dcc.lsu_dtmh_err_b));
2385
2386
2387
2388assign pc_b = mytg ? `PROBES7.pc_1_b :
2389 `PROBES7.pc_0_b;
2390
2391//----------------------------------------------------------
2392// Send Command to NAS
2393
2394always @ (posedge `SPC7.l2clk & ready) begin // {
2395
2396 // if POR|WMR, then no TLBread
2397 if (`TOP.in_reset_core) begin // {
2398
2399 // flush pipeline during reset
2400 irf_error_b_pre <= 0;
2401
2402 rd_vld_w <= 0;
2403 rd_vld_w2 <= 0;
2404 rd_vld_w3 <= 0;
2405
2406 select_pc_w <= 0;
2407 select_pc_w2 <= 0;
2408 select_pc_w3 <= 0;
2409
2410 pc_w <= 0;
2411 pc_w2 <= 0;
2412 pc_w3 <= 0;
2413
2414 end // }
2415 else begin // {
2416
2417 tstamp = `TOP.core_cycle_cnt;
2418
2419 irf_error_b_pre <= irf_error_m;
2420
2421 rd_vld_w <= rd_vld_b;
2422 rd_vld_w2 <= rd_vld_w;
2423 rd_vld_w3 <= rd_vld_w2;
2424
2425 select_pc_w <= select_pc_b;
2426 select_pc_w2 <= select_pc_w;
2427 select_pc_w3 <= select_pc_w2;
2428
2429 pc_w <= pc_b;
2430 pc_w2 <= pc_w;
2431 pc_w3 <= pc_w2;
2432
2433 //---------------------------------
2434 if (rd_vld) begin // {
2435
2436 // Determine which thread is active
2437 for (i=0; i<=3; i=i+1) begin // {
2438 if (select_pc_w3[i]==1'b1) begin // {
2439 mytid = i + (mytg*4);
2440 mytnum = (mycid * 8) + mytid;
2441 end // }
2442 end // }
2443
2444
2445 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2446 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD tid=%d pc=%h ts=%0d",
2447 mycid,mytid,mytnum,pc_w3,tstamp-5);
2448 junk = $sim_send(`PLI_DTLBREAD, mytnum, tstamp-5);
2449
2450 //--------------------
2451 if (`PARGS.show_tlb_on) begin // {
2452 $display ("SHOW_TLB: DTLB_READ C%0d T%0d pc=%h ts=%0d",
2453 mycid,mytid,pc_w3,(tstamp-5)*`TOP.core_period);
2454 end //}
2455
2456 end //}
2457
2458 end // }
2459 end // in_reset}
2460
2461end // always }
2462
2463
2464//---------------------------------------------------------
2465// DTLB POP state machine
2466
2467always @ (posedge `SPC7.l2clk & ready) begin // {
2468
2469 // if POR|WMR, then no TLBread
2470 if (!`TOP.in_reset_core) begin // {
2471
2472 //Set read active when there is a valid lookup
2473 if (rd_vld_b) begin // {
2474 dtlbReadActive[`SPC7.lsu.dcc.tid_b[2:0]] <= 1'h1;
2475 end //}
2476
2477 //Clear it when there is a bypass
2478 if ((`SPC7.lsu.dcc.ld_inst_vld_b |
2479 `SPC7.lsu.dcc.st_inst_vld_b) &
2480 `SPC7.lsu.dcc.tlb_bypass_b &
2481 ~`SPC7.lsu.dcc.flush_all_b) begin // {
2482 dtlbReadActive[`SPC7.lsu.dcc.tid_b[2:0]] <= 1'h0;
2483 end //}
2484
2485 //Do a pop if we are active and then see a Perf Mon
2486 if ((`SPC7.lsu_perfmon_trap_g |
2487 `SPC7.lsu_dcl2u_err_g |
2488 `SPC7.lsu_dcl2nd_err_g) &
2489 dtlbReadActive[`SPC7.lsu_dcerr_tid_g[2:0]]) begin // {
2490 dtlbReadActive[`SPC7.lsu_dcerr_tid_g[2:0]] = 1'h0;
2491
2492 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2493 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
2494 mycid,myLateErrTid,myLateErrTnum,tstamp);
2495 junk = $sim_send(`PLI_DTLBREAD_POP, myLateErrTnum, tstamp);
2496
2497 //--------------------
2498 if (`PARGS.show_tlb_on) begin // {
2499 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
2500 mycid,mytid,tstamp*`TOP.core_period);
2501 end //}
2502 end //}
2503 end //}
2504
2505 // Determine which thread is active
2506 for (i=0; i<=3; i=i+1) begin // {
2507 bsktid = i + (mytg*4);
2508 bsktnum = (mycid * 8) + bsktid;
2509
2510 //Do a pop if we see a block storke kill
2511 if (blockStoreKill[bsktid] &
2512 dtlbReadActive[bsktid]) begin // {
2513 dtlbReadActive[bsktid] = 1'h0;
2514
2515 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2516 `PR_INFO ("pli_tlb", `INFO, "C%0d T%0d PLI_DTLBREAD_POP tid=%d ts=%0d",
2517 mycid,bsktid,bsktnum,tstamp);
2518 junk = $sim_send(`PLI_DTLBREAD_POP, bsktnum, tstamp);
2519
2520 //--------------------
2521 if (`PARGS.show_tlb_on) begin // {
2522 $display ("SHOW_TLB: DTLB_READ_POP C%0d T%0d ts=%0d",
2523 mycid,bsktid,tstamp*`TOP.core_period);
2524 end //}
2525 end // }
2526 end // }
2527
2528 end // for }
2529
2530 end // in_reset}
2531end // always}
2532
2533
2534
2535//----------------------------------------------------------
2536`endif
2537endmodule
2538
2539`endif
2540//----------------------------------------------------------
2541//----------------------------------------------------------