Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / verilog / tlb_sync / dtlb_wr.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: dtlb_wr.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_wr_c0 ();
38`ifndef GATESIM
39
40`include "tlb_sync.vh"
41`include "nas.vh"
42parameter NUM_TLB=128;
43
44wire [7:0] data_in;
45wire [7:0] tlb_wr;
46wire wr_en;
47wire [7:0] entry;
48wire [7:0] asi_num;
49wire asi_enable0; // 1 per thread group
50wire asi_enable1;
51wire [7:0] store_asi; // 1 per thread
52wire [3:0] demap;
53reg [3:0] demap_1;
54wire demap_page;
55wire demap_context;
56wire demap_real;
57wire demap_all;
58wire skip_demap;
59wire demap_active;
60wire auto_demap;
61wire [2:0] demap_tid;
62reg [2:0] demap_tid_1;
63reg [5:0] demap_tnum_1;
64
65reg [(`TS_WIDTH-1):0] tstamp;
66reg hwtw;
67reg [7:0] my_asi [0:7]; // 1 asi number stored per thread
68reg [(`TS_WIDTH-1):0] demap_tstamp;
69
70reg [2:0] mytid;
71reg [5:0] mytnum;
72wire [2:0] mycid;
73integer junk;
74integer i;
75reg [7:0] cnt;
76wire ready;
77
78assign mycid = 0;
79
80`ifdef DEBUG_TLB
81 wire [7:0] my_asi0 = my_asi[0];
82 wire [7:0] my_asi1 = my_asi[1];
83 wire [7:0] my_asi2 = my_asi[2];
84 wire [7:0] my_asi3 = my_asi[3];
85 wire [7:0] my_asi4 = my_asi[4];
86 wire [7:0] my_asi5 = my_asi[5];
87 wire [7:0] my_asi6 = my_asi[6];
88 wire [7:0] my_asi7 = my_asi[7];
89`endif
90
91//----------------------------------------------------------
92// Instantiate fifo - 1 entry per thread
93fifo fifo ();
94// Define fifo parameters
95defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]}
96defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection
97defparam fifo.PTR_BITS = 4;
98
99//----------------------------------------------------------
100// DUT probes
101
102assign data_in = `SPC0.mmu.asi.wrote_dtlb;
103assign tlb_wr = `SPC0.mmu_reload_done;
104assign wr_en = `SPC0.lsu.tlb.tlb_wr_1_in_dout;
105
106assign entry = `SPC0.lsu.tlb.rw_index_1[6:0];
107
108assign asi_num = `PROBES0.asi_num;
109assign asi_enable0 = `PROBES0.tlb_rd_vld_b &
110 !`PROBES0.tlb_bypass_b &
111 `SPC0.tlu.fls0.lsu_inst_b;
112assign asi_enable1 = `PROBES0.tlb_rd_vld_b &
113 !`PROBES0.tlb_bypass_b &
114 `SPC0.tlu.fls1.lsu_inst_b;
115
116assign store_asi[3:0] = asi_enable0 ? `PROBES0.select_pc_b[3:0] : 4'b0;
117assign store_asi[7:4] = asi_enable1 ? `PROBES0.select_pc_b[7:4] : 4'b0;
118
119assign demap_page = `SPC0.lsu.tlc_demap & ~(demap_context | demap_real | demap_all);
120assign demap_context = `SPC0.lsu.tlc_demap_context;
121assign demap_real = `SPC0.lsu.tlc_demap_real;
122assign demap_all = `SPC0.lsu.tlc_demap_all;
123assign demap = {demap_all,demap_page,demap_context,demap_real};
124assign skip_demap =`SPC0.lsu.tlc_wr_u_en;
125assign demap_tid = `SPC0.lsu.tld.tte1[37:35];
126
127// if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS
128assign demap_active = |demap_1 && !skip_demap;
129assign auto_demap = |demap_1 && skip_demap;
130
131//---------------------
132// Probes for debugging
133
134// defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl
135
136// n2_tlb_tl_128x59_cam.sv
137
138`define CNTX1_HI 65
139`define CNTX1_LO 53
140`define PID_HI 52
141`define PID_LO 50
142`define REAL_BIT 49
143`define VA_47 48
144`define VA_28 29
145`define VA_27 28
146`define VA_22 23
147`define TTE_VALID 22
148`define VA_21 21
149`define VA_16 16
150`define VA_15 15
151`define VA_13 13
152`define CNTX0_HI 12
153`define CNTX0_LO 0
154
155// n2_tlb_tl_128x59_ram.sv
156
157`define DATA_PARITY 36
158`define DATA_PA_39_28_HI 35
159`define DATA_PA_39_28_LO 24
160`define DATA_PA_27_22_HI 23
161`define DATA_PA_27_22_LO 18
162`define DATA_VA_27_22_V 17
163`define DATA_PA_21_16_HI 16
164`define DATA_PA_21_16_LO 11
165`define DATA_VA_21_16_V 10
166`define DATA_PA_15_13_HI 9
167`define DATA_PA_15_13_LO 7
168`define DATA_VA_15_13_V 6
169`define DATA_NFO 5
170`define DATA_IE 4
171`define DATA_CP 3
172`define DATA_X 2
173`define DATA_P 1
174`define DATA_W 0
175
176wire [(NUM_TLB-1):0] tlb_valid;
177wire [(NUM_TLB-1):0] tlb_match;
178wire tte_valid;
179wire [47:0] tte_va;
180wire [12:0] tte_context;
181wire tte_real;
182wire [2:0] tte_pid;
183wire [2:0] tte_page_mask;
184wire [39:0] tte_pa;
185wire tte_nfo;
186wire tte_ie;
187wire tte_cp;
188wire tte_e;
189wire tte_p;
190wire tte_w;
191wire tte_ep;
192
193
194assign tlb_valid = `SPC0.lsu.tlb.array.cam.valid;
195assign tlb_match = `SPC0.lsu.tlb.array.cam.match;
196
197assign tte_va = {`SPC0.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28],
198 `SPC0.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22],
199 `SPC0.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16],
200 `SPC0.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13],
201 13'b0
202 };
203assign tte_context = `SPC0.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO];
204assign tte_pid = `SPC0.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO];
205assign tte_real = `SPC0.lsu.tlb.tte_tag_1_dout[`REAL_BIT];
206assign tte_valid = `SPC0.lsu.tlb.tte_tag_1_dout[`TTE_VALID];
207
208assign tte_page_mask = `SPC0.lsu.tlb.tte_page_size_mask_1;
209
210assign tte_pa = {`SPC0.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO],
211 `SPC0.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO],
212 `SPC0.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO],
213 `SPC0.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO],
214 13'b0
215 };
216assign tte_nfo = `SPC0.lsu.tlb.tte_data_1[`DATA_NFO];
217assign tte_ie = `SPC0.lsu.tlb.tte_data_1[`DATA_IE];
218assign tte_cp = `SPC0.lsu.tlb.tte_data_1[`DATA_CP];
219assign tte_e = `SPC0.lsu.tlb.tte_data_1[`DATA_X];
220assign tte_p = `SPC0.lsu.tlb.tte_data_1[`DATA_P];
221assign tte_w = `SPC0.lsu.tlb.tte_data_1[`DATA_W];
222assign tte_ep = 1'bx; // Does not apply for DTLB
223
224assign ready = `PARGS.tlb_sync_on & !`SPC0.tcu_spc_mbist_start;
225
226//----------------------------------------------------------
227// Initialize state machine to idle state
228initial begin // {
229 #1;
230 hwtw = 1'b0;
231 for (i=0; i<=7; i=i+1) begin
232 my_asi[i] = 8'b0;
233 end
234 @ (posedge `SPC0.l2clk);
235
236end // }
237
238//----------------------------------------------------------
239// Must use negedge to avoid race condition
240// tlb_entry_replace (aka entry) is created in always block using blocking assignments
241
242always @ (negedge (`SPC0.l2clk & ready)) begin // {
243
244 tstamp = `TOP.core_cycle_cnt;
245 demap_tstamp = `TOP.core_cycle_cnt;
246
247 // Delay by 1 cycle to align with skip_demap
248 demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted
249 demap_tnum_1 <= (mycid * 8) + demap_tid;
250 demap_1 <= demap;
251
252 //----------------------------------------------------------
253 // Send I/DTLBWRITE due to demap
254 //
255
256 if ((demap!=0) && (demap_1!=0)) begin // {
257 `PR_ERROR ("tlb_sync", `ERROR,
258 "C%0d T%0d Illegal Back to Back DTLB demap",
259 mycid,demap_tid_1);
260 end // }
261
262 if (demap_active) begin // {
263 fifo.pop_fifo ({hwtw,mytid});
264 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
265 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h (demap)",
266 mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff);
267 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
268 mycid,demap_tid_1,demap_tnum_1,demap_tstamp);
269 junk = $sim_send(`PLI_DTLBWRITE, demap_tnum_1,demap_tstamp,8'hff);
270 junk = $sim_send(`PLI_SSTEP, demap_tnum_1);
271
272 // sstep_sent is asserted when data_in is asserted
273 // Check to see if sstep was sent early
274 if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // {
275 `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture
276 end //}
277
278 end //}
279 end //}
280
281 //--------------------
282 if (`PARGS.show_tlb_on & (|demap_1)) begin // {
283 $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1);
284
285 if (demap_active) begin
286 case (demap_1)
287 4'b0001: $write ("type=real ");
288 4'b0010: $write ("type=cntx ");
289 4'b0100: $write ("type=page ");
290 4'b1000: $write ("type=all ");
291 default:
292 `PR_ERROR ("tlb_sync", `ERROR,
293 "Bench Problem - demap_1(%b) should be one-hot.",demap_1);
294 endcase
295 end
296 else begin
297 $write ("type=autodemap ");
298 end
299
300 $display ("match=%h ts=%0d",
301 tlb_match,demap_tstamp*`TOP.core_period);
302
303 for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // {
304 if (tlb_match[cnt]==1'b1) begin // {
305 $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d",
306 mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period);
307 end // }
308 end // }
309 //--------------------
310 end // }
311
312 //----------------------------------------------------------
313 // Send I/DHWTW due to HWTW
314 // Send I/DTLBWRITE due to ASI write
315
316 // Save asi num when DTLBREAD happens.
317 // Otherwise, hold state.
318 // Send asi num later with DHWTW
319 for (i=0;i<=7;i=i+1) begin // {
320 my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i];
321 end // }
322
323 // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en)
324 // These signals will be interleaved between the threads.
325 // Need to queue up the signals over time so they can be processed in order.
326 // Each thread will only be doing 1 thing at a time.
327
328 for (i=0;i<=7;i=i+1) begin // {
329
330 // tlb_wr[tid] determines if the write is HWTW or TLBWRITE
331
332 // data_in[tid] determines which thread will write next
333 // Use fifo to save the tids of the data_in signals in order
334
335 if (data_in[i]) begin // {
336 if (tlb_wr[i]) begin // {
337 fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]}
338 end // }
339 else begin // {
340 fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]}
341
342 // Signal to nas_pipe to suppress SSTEP as soon we know a tlb write or demap is coming (data_in=1)
343 // Cannot wait for wr_en because it is possible to miss an SSTEP.
344 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)",
345 mycid,i,((mycid * 6'h8) + i[2:0]),tstamp);
346 `NASTOP.sstep_sent[(mycid * 6'h8) + i[2:0]] <= 1'b1; // suppress SSTEP
347 end // }
348 end // }
349
350 end // }
351
352 //----------------------------------------------------------
353 // wr_en means that the write is occurring
354 if (wr_en) begin // {
355 fifo.pop_fifo ({hwtw,mytid});
356 mytnum = (mycid * 8) + mytid;
357
358 if (hwtw) begin // {
359 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
360 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DHWTW tid=%d ts=%0d va=%h asi=%h entry=%h",
361 mycid,mytid,mytnum,tstamp,tte_va,my_asi[mytid],entry);
362 junk = $sim_send(`PLI_DHWTW, mytnum,tstamp,tte_va,my_asi[mytid],entry);
363
364 end //}
365 end // }
366 else begin // {
367 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
368 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h",
369 mycid,mytid,mytnum,tstamp,entry);
370 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
371 mycid,mytid,mytnum,tstamp);
372 junk = $sim_send(`PLI_DTLBWRITE, mytnum,tstamp,entry);
373 junk = $sim_send(`PLI_SSTEP, mytnum);
374
375 // Check to see if sstep was sent early
376 if (`NASTOP.sstep_sent[mytnum]==1) begin // {
377 `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture
378 end //}
379
380 end //}
381 end // }
382
383 //--------------------
384 if (`PARGS.show_tlb_on) begin // {
385 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
386
387 if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va);
388 else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va);
389
390 case (tte_page_mask)
391 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d",
392 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
393 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d",
394 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
395 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d",
396 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
397 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d",
398 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
399 endcase
400
401 if (hwtw) $display (" (hwtw)");
402 else $display ("");
403
404 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
405
406 $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d",
407 tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period);
408 end // }
409 //--------------------
410
411 end // }
412
413end // always}
414
415//----------------------------------------------------------
416`endif
417endmodule
418
419`endif
420`ifdef CORE_1
421
422module dtlb_wr_c1 ();
423`ifndef GATESIM
424
425`include "tlb_sync.vh"
426`include "nas.vh"
427parameter NUM_TLB=128;
428
429wire [7:0] data_in;
430wire [7:0] tlb_wr;
431wire wr_en;
432wire [7:0] entry;
433wire [7:0] asi_num;
434wire asi_enable0; // 1 per thread group
435wire asi_enable1;
436wire [7:0] store_asi; // 1 per thread
437wire [3:0] demap;
438reg [3:0] demap_1;
439wire demap_page;
440wire demap_context;
441wire demap_real;
442wire demap_all;
443wire skip_demap;
444wire demap_active;
445wire auto_demap;
446wire [2:0] demap_tid;
447reg [2:0] demap_tid_1;
448reg [5:0] demap_tnum_1;
449
450reg [(`TS_WIDTH-1):0] tstamp;
451reg hwtw;
452reg [7:0] my_asi [0:7]; // 1 asi number stored per thread
453reg [(`TS_WIDTH-1):0] demap_tstamp;
454
455reg [2:0] mytid;
456reg [5:0] mytnum;
457wire [2:0] mycid;
458integer junk;
459integer i;
460reg [7:0] cnt;
461wire ready;
462
463assign mycid = 1;
464
465`ifdef DEBUG_TLB
466 wire [7:0] my_asi0 = my_asi[0];
467 wire [7:0] my_asi1 = my_asi[1];
468 wire [7:0] my_asi2 = my_asi[2];
469 wire [7:0] my_asi3 = my_asi[3];
470 wire [7:0] my_asi4 = my_asi[4];
471 wire [7:0] my_asi5 = my_asi[5];
472 wire [7:0] my_asi6 = my_asi[6];
473 wire [7:0] my_asi7 = my_asi[7];
474`endif
475
476//----------------------------------------------------------
477// Instantiate fifo - 1 entry per thread
478fifo fifo ();
479// Define fifo parameters
480defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]}
481defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection
482defparam fifo.PTR_BITS = 4;
483
484//----------------------------------------------------------
485// DUT probes
486
487assign data_in = `SPC1.mmu.asi.wrote_dtlb;
488assign tlb_wr = `SPC1.mmu_reload_done;
489assign wr_en = `SPC1.lsu.tlb.tlb_wr_1_in_dout;
490
491assign entry = `SPC1.lsu.tlb.rw_index_1[6:0];
492
493assign asi_num = `PROBES1.asi_num;
494assign asi_enable0 = `PROBES1.tlb_rd_vld_b &
495 !`PROBES1.tlb_bypass_b &
496 `SPC1.tlu.fls0.lsu_inst_b;
497assign asi_enable1 = `PROBES1.tlb_rd_vld_b &
498 !`PROBES1.tlb_bypass_b &
499 `SPC1.tlu.fls1.lsu_inst_b;
500
501assign store_asi[3:0] = asi_enable0 ? `PROBES1.select_pc_b[3:0] : 4'b0;
502assign store_asi[7:4] = asi_enable1 ? `PROBES1.select_pc_b[7:4] : 4'b0;
503
504assign demap_page = `SPC1.lsu.tlc_demap & ~(demap_context | demap_real | demap_all);
505assign demap_context = `SPC1.lsu.tlc_demap_context;
506assign demap_real = `SPC1.lsu.tlc_demap_real;
507assign demap_all = `SPC1.lsu.tlc_demap_all;
508assign demap = {demap_all,demap_page,demap_context,demap_real};
509assign skip_demap =`SPC1.lsu.tlc_wr_u_en;
510assign demap_tid = `SPC1.lsu.tld.tte1[37:35];
511
512// if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS
513assign demap_active = |demap_1 && !skip_demap;
514assign auto_demap = |demap_1 && skip_demap;
515
516//---------------------
517// Probes for debugging
518
519// defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl
520
521// n2_tlb_tl_128x59_cam.sv
522
523`define CNTX1_HI 65
524`define CNTX1_LO 53
525`define PID_HI 52
526`define PID_LO 50
527`define REAL_BIT 49
528`define VA_47 48
529`define VA_28 29
530`define VA_27 28
531`define VA_22 23
532`define TTE_VALID 22
533`define VA_21 21
534`define VA_16 16
535`define VA_15 15
536`define VA_13 13
537`define CNTX0_HI 12
538`define CNTX0_LO 0
539
540// n2_tlb_tl_128x59_ram.sv
541
542`define DATA_PARITY 36
543`define DATA_PA_39_28_HI 35
544`define DATA_PA_39_28_LO 24
545`define DATA_PA_27_22_HI 23
546`define DATA_PA_27_22_LO 18
547`define DATA_VA_27_22_V 17
548`define DATA_PA_21_16_HI 16
549`define DATA_PA_21_16_LO 11
550`define DATA_VA_21_16_V 10
551`define DATA_PA_15_13_HI 9
552`define DATA_PA_15_13_LO 7
553`define DATA_VA_15_13_V 6
554`define DATA_NFO 5
555`define DATA_IE 4
556`define DATA_CP 3
557`define DATA_X 2
558`define DATA_P 1
559`define DATA_W 0
560
561wire [(NUM_TLB-1):0] tlb_valid;
562wire [(NUM_TLB-1):0] tlb_match;
563wire tte_valid;
564wire [47:0] tte_va;
565wire [12:0] tte_context;
566wire tte_real;
567wire [2:0] tte_pid;
568wire [2:0] tte_page_mask;
569wire [39:0] tte_pa;
570wire tte_nfo;
571wire tte_ie;
572wire tte_cp;
573wire tte_e;
574wire tte_p;
575wire tte_w;
576wire tte_ep;
577
578
579assign tlb_valid = `SPC1.lsu.tlb.array.cam.valid;
580assign tlb_match = `SPC1.lsu.tlb.array.cam.match;
581
582assign tte_va = {`SPC1.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28],
583 `SPC1.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22],
584 `SPC1.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16],
585 `SPC1.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13],
586 13'b0
587 };
588assign tte_context = `SPC1.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO];
589assign tte_pid = `SPC1.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO];
590assign tte_real = `SPC1.lsu.tlb.tte_tag_1_dout[`REAL_BIT];
591assign tte_valid = `SPC1.lsu.tlb.tte_tag_1_dout[`TTE_VALID];
592
593assign tte_page_mask = `SPC1.lsu.tlb.tte_page_size_mask_1;
594
595assign tte_pa = {`SPC1.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO],
596 `SPC1.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO],
597 `SPC1.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO],
598 `SPC1.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO],
599 13'b0
600 };
601assign tte_nfo = `SPC1.lsu.tlb.tte_data_1[`DATA_NFO];
602assign tte_ie = `SPC1.lsu.tlb.tte_data_1[`DATA_IE];
603assign tte_cp = `SPC1.lsu.tlb.tte_data_1[`DATA_CP];
604assign tte_e = `SPC1.lsu.tlb.tte_data_1[`DATA_X];
605assign tte_p = `SPC1.lsu.tlb.tte_data_1[`DATA_P];
606assign tte_w = `SPC1.lsu.tlb.tte_data_1[`DATA_W];
607assign tte_ep = 1'bx; // Does not apply for DTLB
608
609assign ready = `PARGS.tlb_sync_on & !`SPC1.tcu_spc_mbist_start;
610
611//----------------------------------------------------------
612// Initialize state machine to idle state
613initial begin // {
614 #1;
615 hwtw = 1'b0;
616 for (i=0; i<=7; i=i+1) begin
617 my_asi[i] = 8'b0;
618 end
619 @ (posedge `SPC1.l2clk);
620
621end // }
622
623//----------------------------------------------------------
624// Must use negedge to avoid race condition
625// tlb_entry_replace (aka entry) is created in always block using blocking assignments
626
627always @ (negedge (`SPC1.l2clk & ready)) begin // {
628
629 tstamp = `TOP.core_cycle_cnt;
630 demap_tstamp = `TOP.core_cycle_cnt;
631
632 // Delay by 1 cycle to align with skip_demap
633 demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted
634 demap_tnum_1 <= (mycid * 8) + demap_tid;
635 demap_1 <= demap;
636
637 //----------------------------------------------------------
638 // Send I/DTLBWRITE due to demap
639 //
640
641 if ((demap!=0) && (demap_1!=0)) begin // {
642 `PR_ERROR ("tlb_sync", `ERROR,
643 "C%0d T%0d Illegal Back to Back DTLB demap",
644 mycid,demap_tid_1);
645 end // }
646
647 if (demap_active) begin // {
648 fifo.pop_fifo ({hwtw,mytid});
649 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
650 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h (demap)",
651 mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff);
652 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
653 mycid,demap_tid_1,demap_tnum_1,demap_tstamp);
654 junk = $sim_send(`PLI_DTLBWRITE, demap_tnum_1,demap_tstamp,8'hff);
655 junk = $sim_send(`PLI_SSTEP, demap_tnum_1);
656
657 // sstep_sent is asserted when data_in is asserted
658 // Check to see if sstep was sent early
659 if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // {
660 `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture
661 end //}
662
663 end //}
664 end //}
665
666 //--------------------
667 if (`PARGS.show_tlb_on & (|demap_1)) begin // {
668 $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1);
669
670 if (demap_active) begin
671 case (demap_1)
672 4'b0001: $write ("type=real ");
673 4'b0010: $write ("type=cntx ");
674 4'b0100: $write ("type=page ");
675 4'b1000: $write ("type=all ");
676 default:
677 `PR_ERROR ("tlb_sync", `ERROR,
678 "Bench Problem - demap_1(%b) should be one-hot.",demap_1);
679 endcase
680 end
681 else begin
682 $write ("type=autodemap ");
683 end
684
685 $display ("match=%h ts=%0d",
686 tlb_match,demap_tstamp*`TOP.core_period);
687
688 for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // {
689 if (tlb_match[cnt]==1'b1) begin // {
690 $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d",
691 mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period);
692 end // }
693 end // }
694 //--------------------
695 end // }
696
697 //----------------------------------------------------------
698 // Send I/DHWTW due to HWTW
699 // Send I/DTLBWRITE due to ASI write
700
701 // Save asi num when DTLBREAD happens.
702 // Otherwise, hold state.
703 // Send asi num later with DHWTW
704 for (i=0;i<=7;i=i+1) begin // {
705 my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i];
706 end // }
707
708 // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en)
709 // These signals will be interleaved between the threads.
710 // Need to queue up the signals over time so they can be processed in order.
711 // Each thread will only be doing 1 thing at a time.
712
713 for (i=0;i<=7;i=i+1) begin // {
714
715 // tlb_wr[tid] determines if the write is HWTW or TLBWRITE
716
717 // data_in[tid] determines which thread will write next
718 // Use fifo to save the tids of the data_in signals in order
719
720 if (data_in[i]) begin // {
721 if (tlb_wr[i]) begin // {
722 fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]}
723 end // }
724 else begin // {
725 fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]}
726
727 // Signal to nas_pipe to suppress SSTEP as soon we know a tlb write or demap is coming (data_in=1)
728 // Cannot wait for wr_en because it is possible to miss an SSTEP.
729 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)",
730 mycid,i,((mycid * 6'h8) + i[2:0]),tstamp);
731 `NASTOP.sstep_sent[(mycid * 6'h8) + i[2:0]] <= 1'b1; // suppress SSTEP
732 end // }
733 end // }
734
735 end // }
736
737 //----------------------------------------------------------
738 // wr_en means that the write is occurring
739 if (wr_en) begin // {
740 fifo.pop_fifo ({hwtw,mytid});
741 mytnum = (mycid * 8) + mytid;
742
743 if (hwtw) begin // {
744 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
745 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DHWTW tid=%d ts=%0d va=%h asi=%h entry=%h",
746 mycid,mytid,mytnum,tstamp,tte_va,my_asi[mytid],entry);
747 junk = $sim_send(`PLI_DHWTW, mytnum,tstamp,tte_va,my_asi[mytid],entry);
748
749 end //}
750 end // }
751 else begin // {
752 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
753 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h",
754 mycid,mytid,mytnum,tstamp,entry);
755 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
756 mycid,mytid,mytnum,tstamp);
757 junk = $sim_send(`PLI_DTLBWRITE, mytnum,tstamp,entry);
758 junk = $sim_send(`PLI_SSTEP, mytnum);
759
760 // Check to see if sstep was sent early
761 if (`NASTOP.sstep_sent[mytnum]==1) begin // {
762 `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture
763 end //}
764
765 end //}
766 end // }
767
768 //--------------------
769 if (`PARGS.show_tlb_on) begin // {
770 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
771
772 if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va);
773 else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va);
774
775 case (tte_page_mask)
776 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d",
777 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
778 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d",
779 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
780 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d",
781 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
782 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d",
783 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
784 endcase
785
786 if (hwtw) $display (" (hwtw)");
787 else $display ("");
788
789 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
790
791 $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d",
792 tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period);
793 end // }
794 //--------------------
795
796 end // }
797
798end // always}
799
800//----------------------------------------------------------
801`endif
802endmodule
803
804`endif
805`ifdef CORE_2
806
807module dtlb_wr_c2 ();
808`ifndef GATESIM
809
810`include "tlb_sync.vh"
811`include "nas.vh"
812parameter NUM_TLB=128;
813
814wire [7:0] data_in;
815wire [7:0] tlb_wr;
816wire wr_en;
817wire [7:0] entry;
818wire [7:0] asi_num;
819wire asi_enable0; // 1 per thread group
820wire asi_enable1;
821wire [7:0] store_asi; // 1 per thread
822wire [3:0] demap;
823reg [3:0] demap_1;
824wire demap_page;
825wire demap_context;
826wire demap_real;
827wire demap_all;
828wire skip_demap;
829wire demap_active;
830wire auto_demap;
831wire [2:0] demap_tid;
832reg [2:0] demap_tid_1;
833reg [5:0] demap_tnum_1;
834
835reg [(`TS_WIDTH-1):0] tstamp;
836reg hwtw;
837reg [7:0] my_asi [0:7]; // 1 asi number stored per thread
838reg [(`TS_WIDTH-1):0] demap_tstamp;
839
840reg [2:0] mytid;
841reg [5:0] mytnum;
842wire [2:0] mycid;
843integer junk;
844integer i;
845reg [7:0] cnt;
846wire ready;
847
848assign mycid = 2;
849
850`ifdef DEBUG_TLB
851 wire [7:0] my_asi0 = my_asi[0];
852 wire [7:0] my_asi1 = my_asi[1];
853 wire [7:0] my_asi2 = my_asi[2];
854 wire [7:0] my_asi3 = my_asi[3];
855 wire [7:0] my_asi4 = my_asi[4];
856 wire [7:0] my_asi5 = my_asi[5];
857 wire [7:0] my_asi6 = my_asi[6];
858 wire [7:0] my_asi7 = my_asi[7];
859`endif
860
861//----------------------------------------------------------
862// Instantiate fifo - 1 entry per thread
863fifo fifo ();
864// Define fifo parameters
865defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]}
866defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection
867defparam fifo.PTR_BITS = 4;
868
869//----------------------------------------------------------
870// DUT probes
871
872assign data_in = `SPC2.mmu.asi.wrote_dtlb;
873assign tlb_wr = `SPC2.mmu_reload_done;
874assign wr_en = `SPC2.lsu.tlb.tlb_wr_1_in_dout;
875
876assign entry = `SPC2.lsu.tlb.rw_index_1[6:0];
877
878assign asi_num = `PROBES2.asi_num;
879assign asi_enable0 = `PROBES2.tlb_rd_vld_b &
880 !`PROBES2.tlb_bypass_b &
881 `SPC2.tlu.fls0.lsu_inst_b;
882assign asi_enable1 = `PROBES2.tlb_rd_vld_b &
883 !`PROBES2.tlb_bypass_b &
884 `SPC2.tlu.fls1.lsu_inst_b;
885
886assign store_asi[3:0] = asi_enable0 ? `PROBES2.select_pc_b[3:0] : 4'b0;
887assign store_asi[7:4] = asi_enable1 ? `PROBES2.select_pc_b[7:4] : 4'b0;
888
889assign demap_page = `SPC2.lsu.tlc_demap & ~(demap_context | demap_real | demap_all);
890assign demap_context = `SPC2.lsu.tlc_demap_context;
891assign demap_real = `SPC2.lsu.tlc_demap_real;
892assign demap_all = `SPC2.lsu.tlc_demap_all;
893assign demap = {demap_all,demap_page,demap_context,demap_real};
894assign skip_demap =`SPC2.lsu.tlc_wr_u_en;
895assign demap_tid = `SPC2.lsu.tld.tte1[37:35];
896
897// if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS
898assign demap_active = |demap_1 && !skip_demap;
899assign auto_demap = |demap_1 && skip_demap;
900
901//---------------------
902// Probes for debugging
903
904// defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl
905
906// n2_tlb_tl_128x59_cam.sv
907
908`define CNTX1_HI 65
909`define CNTX1_LO 53
910`define PID_HI 52
911`define PID_LO 50
912`define REAL_BIT 49
913`define VA_47 48
914`define VA_28 29
915`define VA_27 28
916`define VA_22 23
917`define TTE_VALID 22
918`define VA_21 21
919`define VA_16 16
920`define VA_15 15
921`define VA_13 13
922`define CNTX0_HI 12
923`define CNTX0_LO 0
924
925// n2_tlb_tl_128x59_ram.sv
926
927`define DATA_PARITY 36
928`define DATA_PA_39_28_HI 35
929`define DATA_PA_39_28_LO 24
930`define DATA_PA_27_22_HI 23
931`define DATA_PA_27_22_LO 18
932`define DATA_VA_27_22_V 17
933`define DATA_PA_21_16_HI 16
934`define DATA_PA_21_16_LO 11
935`define DATA_VA_21_16_V 10
936`define DATA_PA_15_13_HI 9
937`define DATA_PA_15_13_LO 7
938`define DATA_VA_15_13_V 6
939`define DATA_NFO 5
940`define DATA_IE 4
941`define DATA_CP 3
942`define DATA_X 2
943`define DATA_P 1
944`define DATA_W 0
945
946wire [(NUM_TLB-1):0] tlb_valid;
947wire [(NUM_TLB-1):0] tlb_match;
948wire tte_valid;
949wire [47:0] tte_va;
950wire [12:0] tte_context;
951wire tte_real;
952wire [2:0] tte_pid;
953wire [2:0] tte_page_mask;
954wire [39:0] tte_pa;
955wire tte_nfo;
956wire tte_ie;
957wire tte_cp;
958wire tte_e;
959wire tte_p;
960wire tte_w;
961wire tte_ep;
962
963
964assign tlb_valid = `SPC2.lsu.tlb.array.cam.valid;
965assign tlb_match = `SPC2.lsu.tlb.array.cam.match;
966
967assign tte_va = {`SPC2.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28],
968 `SPC2.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22],
969 `SPC2.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16],
970 `SPC2.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13],
971 13'b0
972 };
973assign tte_context = `SPC2.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO];
974assign tte_pid = `SPC2.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO];
975assign tte_real = `SPC2.lsu.tlb.tte_tag_1_dout[`REAL_BIT];
976assign tte_valid = `SPC2.lsu.tlb.tte_tag_1_dout[`TTE_VALID];
977
978assign tte_page_mask = `SPC2.lsu.tlb.tte_page_size_mask_1;
979
980assign tte_pa = {`SPC2.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO],
981 `SPC2.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO],
982 `SPC2.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO],
983 `SPC2.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO],
984 13'b0
985 };
986assign tte_nfo = `SPC2.lsu.tlb.tte_data_1[`DATA_NFO];
987assign tte_ie = `SPC2.lsu.tlb.tte_data_1[`DATA_IE];
988assign tte_cp = `SPC2.lsu.tlb.tte_data_1[`DATA_CP];
989assign tte_e = `SPC2.lsu.tlb.tte_data_1[`DATA_X];
990assign tte_p = `SPC2.lsu.tlb.tte_data_1[`DATA_P];
991assign tte_w = `SPC2.lsu.tlb.tte_data_1[`DATA_W];
992assign tte_ep = 1'bx; // Does not apply for DTLB
993
994assign ready = `PARGS.tlb_sync_on & !`SPC2.tcu_spc_mbist_start;
995
996//----------------------------------------------------------
997// Initialize state machine to idle state
998initial begin // {
999 #1;
1000 hwtw = 1'b0;
1001 for (i=0; i<=7; i=i+1) begin
1002 my_asi[i] = 8'b0;
1003 end
1004 @ (posedge `SPC2.l2clk);
1005
1006end // }
1007
1008//----------------------------------------------------------
1009// Must use negedge to avoid race condition
1010// tlb_entry_replace (aka entry) is created in always block using blocking assignments
1011
1012always @ (negedge (`SPC2.l2clk & ready)) begin // {
1013
1014 tstamp = `TOP.core_cycle_cnt;
1015 demap_tstamp = `TOP.core_cycle_cnt;
1016
1017 // Delay by 1 cycle to align with skip_demap
1018 demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted
1019 demap_tnum_1 <= (mycid * 8) + demap_tid;
1020 demap_1 <= demap;
1021
1022 //----------------------------------------------------------
1023 // Send I/DTLBWRITE due to demap
1024 //
1025
1026 if ((demap!=0) && (demap_1!=0)) begin // {
1027 `PR_ERROR ("tlb_sync", `ERROR,
1028 "C%0d T%0d Illegal Back to Back DTLB demap",
1029 mycid,demap_tid_1);
1030 end // }
1031
1032 if (demap_active) begin // {
1033 fifo.pop_fifo ({hwtw,mytid});
1034 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1035 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h (demap)",
1036 mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff);
1037 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
1038 mycid,demap_tid_1,demap_tnum_1,demap_tstamp);
1039 junk = $sim_send(`PLI_DTLBWRITE, demap_tnum_1,demap_tstamp,8'hff);
1040 junk = $sim_send(`PLI_SSTEP, demap_tnum_1);
1041
1042 // sstep_sent is asserted when data_in is asserted
1043 // Check to see if sstep was sent early
1044 if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // {
1045 `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture
1046 end //}
1047
1048 end //}
1049 end //}
1050
1051 //--------------------
1052 if (`PARGS.show_tlb_on & (|demap_1)) begin // {
1053 $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1);
1054
1055 if (demap_active) begin
1056 case (demap_1)
1057 4'b0001: $write ("type=real ");
1058 4'b0010: $write ("type=cntx ");
1059 4'b0100: $write ("type=page ");
1060 4'b1000: $write ("type=all ");
1061 default:
1062 `PR_ERROR ("tlb_sync", `ERROR,
1063 "Bench Problem - demap_1(%b) should be one-hot.",demap_1);
1064 endcase
1065 end
1066 else begin
1067 $write ("type=autodemap ");
1068 end
1069
1070 $display ("match=%h ts=%0d",
1071 tlb_match,demap_tstamp*`TOP.core_period);
1072
1073 for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // {
1074 if (tlb_match[cnt]==1'b1) begin // {
1075 $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d",
1076 mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period);
1077 end // }
1078 end // }
1079 //--------------------
1080 end // }
1081
1082 //----------------------------------------------------------
1083 // Send I/DHWTW due to HWTW
1084 // Send I/DTLBWRITE due to ASI write
1085
1086 // Save asi num when DTLBREAD happens.
1087 // Otherwise, hold state.
1088 // Send asi num later with DHWTW
1089 for (i=0;i<=7;i=i+1) begin // {
1090 my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i];
1091 end // }
1092
1093 // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en)
1094 // These signals will be interleaved between the threads.
1095 // Need to queue up the signals over time so they can be processed in order.
1096 // Each thread will only be doing 1 thing at a time.
1097
1098 for (i=0;i<=7;i=i+1) begin // {
1099
1100 // tlb_wr[tid] determines if the write is HWTW or TLBWRITE
1101
1102 // data_in[tid] determines which thread will write next
1103 // Use fifo to save the tids of the data_in signals in order
1104
1105 if (data_in[i]) begin // {
1106 if (tlb_wr[i]) begin // {
1107 fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]}
1108 end // }
1109 else begin // {
1110 fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]}
1111
1112 // Signal to nas_pipe to suppress SSTEP as soon we know a tlb write or demap is coming (data_in=1)
1113 // Cannot wait for wr_en because it is possible to miss an SSTEP.
1114 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)",
1115 mycid,i,((mycid * 6'h8) + i[2:0]),tstamp);
1116 `NASTOP.sstep_sent[(mycid * 6'h8) + i[2:0]] <= 1'b1; // suppress SSTEP
1117 end // }
1118 end // }
1119
1120 end // }
1121
1122 //----------------------------------------------------------
1123 // wr_en means that the write is occurring
1124 if (wr_en) begin // {
1125 fifo.pop_fifo ({hwtw,mytid});
1126 mytnum = (mycid * 8) + mytid;
1127
1128 if (hwtw) begin // {
1129 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1130 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DHWTW tid=%d ts=%0d va=%h asi=%h entry=%h",
1131 mycid,mytid,mytnum,tstamp,tte_va,my_asi[mytid],entry);
1132 junk = $sim_send(`PLI_DHWTW, mytnum,tstamp,tte_va,my_asi[mytid],entry);
1133
1134 end //}
1135 end // }
1136 else begin // {
1137 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1138 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h",
1139 mycid,mytid,mytnum,tstamp,entry);
1140 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
1141 mycid,mytid,mytnum,tstamp);
1142 junk = $sim_send(`PLI_DTLBWRITE, mytnum,tstamp,entry);
1143 junk = $sim_send(`PLI_SSTEP, mytnum);
1144
1145 // Check to see if sstep was sent early
1146 if (`NASTOP.sstep_sent[mytnum]==1) begin // {
1147 `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture
1148 end //}
1149
1150 end //}
1151 end // }
1152
1153 //--------------------
1154 if (`PARGS.show_tlb_on) begin // {
1155 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
1156
1157 if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va);
1158 else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va);
1159
1160 case (tte_page_mask)
1161 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d",
1162 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
1163 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d",
1164 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
1165 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d",
1166 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
1167 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d",
1168 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
1169 endcase
1170
1171 if (hwtw) $display (" (hwtw)");
1172 else $display ("");
1173
1174 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
1175
1176 $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d",
1177 tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period);
1178 end // }
1179 //--------------------
1180
1181 end // }
1182
1183end // always}
1184
1185//----------------------------------------------------------
1186`endif
1187endmodule
1188
1189`endif
1190`ifdef CORE_3
1191
1192module dtlb_wr_c3 ();
1193`ifndef GATESIM
1194
1195`include "tlb_sync.vh"
1196`include "nas.vh"
1197parameter NUM_TLB=128;
1198
1199wire [7:0] data_in;
1200wire [7:0] tlb_wr;
1201wire wr_en;
1202wire [7:0] entry;
1203wire [7:0] asi_num;
1204wire asi_enable0; // 1 per thread group
1205wire asi_enable1;
1206wire [7:0] store_asi; // 1 per thread
1207wire [3:0] demap;
1208reg [3:0] demap_1;
1209wire demap_page;
1210wire demap_context;
1211wire demap_real;
1212wire demap_all;
1213wire skip_demap;
1214wire demap_active;
1215wire auto_demap;
1216wire [2:0] demap_tid;
1217reg [2:0] demap_tid_1;
1218reg [5:0] demap_tnum_1;
1219
1220reg [(`TS_WIDTH-1):0] tstamp;
1221reg hwtw;
1222reg [7:0] my_asi [0:7]; // 1 asi number stored per thread
1223reg [(`TS_WIDTH-1):0] demap_tstamp;
1224
1225reg [2:0] mytid;
1226reg [5:0] mytnum;
1227wire [2:0] mycid;
1228integer junk;
1229integer i;
1230reg [7:0] cnt;
1231wire ready;
1232
1233assign mycid = 3;
1234
1235`ifdef DEBUG_TLB
1236 wire [7:0] my_asi0 = my_asi[0];
1237 wire [7:0] my_asi1 = my_asi[1];
1238 wire [7:0] my_asi2 = my_asi[2];
1239 wire [7:0] my_asi3 = my_asi[3];
1240 wire [7:0] my_asi4 = my_asi[4];
1241 wire [7:0] my_asi5 = my_asi[5];
1242 wire [7:0] my_asi6 = my_asi[6];
1243 wire [7:0] my_asi7 = my_asi[7];
1244`endif
1245
1246//----------------------------------------------------------
1247// Instantiate fifo - 1 entry per thread
1248fifo fifo ();
1249// Define fifo parameters
1250defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]}
1251defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection
1252defparam fifo.PTR_BITS = 4;
1253
1254//----------------------------------------------------------
1255// DUT probes
1256
1257assign data_in = `SPC3.mmu.asi.wrote_dtlb;
1258assign tlb_wr = `SPC3.mmu_reload_done;
1259assign wr_en = `SPC3.lsu.tlb.tlb_wr_1_in_dout;
1260
1261assign entry = `SPC3.lsu.tlb.rw_index_1[6:0];
1262
1263assign asi_num = `PROBES3.asi_num;
1264assign asi_enable0 = `PROBES3.tlb_rd_vld_b &
1265 !`PROBES3.tlb_bypass_b &
1266 `SPC3.tlu.fls0.lsu_inst_b;
1267assign asi_enable1 = `PROBES3.tlb_rd_vld_b &
1268 !`PROBES3.tlb_bypass_b &
1269 `SPC3.tlu.fls1.lsu_inst_b;
1270
1271assign store_asi[3:0] = asi_enable0 ? `PROBES3.select_pc_b[3:0] : 4'b0;
1272assign store_asi[7:4] = asi_enable1 ? `PROBES3.select_pc_b[7:4] : 4'b0;
1273
1274assign demap_page = `SPC3.lsu.tlc_demap & ~(demap_context | demap_real | demap_all);
1275assign demap_context = `SPC3.lsu.tlc_demap_context;
1276assign demap_real = `SPC3.lsu.tlc_demap_real;
1277assign demap_all = `SPC3.lsu.tlc_demap_all;
1278assign demap = {demap_all,demap_page,demap_context,demap_real};
1279assign skip_demap =`SPC3.lsu.tlc_wr_u_en;
1280assign demap_tid = `SPC3.lsu.tld.tte1[37:35];
1281
1282// if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS
1283assign demap_active = |demap_1 && !skip_demap;
1284assign auto_demap = |demap_1 && skip_demap;
1285
1286//---------------------
1287// Probes for debugging
1288
1289// defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl
1290
1291// n2_tlb_tl_128x59_cam.sv
1292
1293`define CNTX1_HI 65
1294`define CNTX1_LO 53
1295`define PID_HI 52
1296`define PID_LO 50
1297`define REAL_BIT 49
1298`define VA_47 48
1299`define VA_28 29
1300`define VA_27 28
1301`define VA_22 23
1302`define TTE_VALID 22
1303`define VA_21 21
1304`define VA_16 16
1305`define VA_15 15
1306`define VA_13 13
1307`define CNTX0_HI 12
1308`define CNTX0_LO 0
1309
1310// n2_tlb_tl_128x59_ram.sv
1311
1312`define DATA_PARITY 36
1313`define DATA_PA_39_28_HI 35
1314`define DATA_PA_39_28_LO 24
1315`define DATA_PA_27_22_HI 23
1316`define DATA_PA_27_22_LO 18
1317`define DATA_VA_27_22_V 17
1318`define DATA_PA_21_16_HI 16
1319`define DATA_PA_21_16_LO 11
1320`define DATA_VA_21_16_V 10
1321`define DATA_PA_15_13_HI 9
1322`define DATA_PA_15_13_LO 7
1323`define DATA_VA_15_13_V 6
1324`define DATA_NFO 5
1325`define DATA_IE 4
1326`define DATA_CP 3
1327`define DATA_X 2
1328`define DATA_P 1
1329`define DATA_W 0
1330
1331wire [(NUM_TLB-1):0] tlb_valid;
1332wire [(NUM_TLB-1):0] tlb_match;
1333wire tte_valid;
1334wire [47:0] tte_va;
1335wire [12:0] tte_context;
1336wire tte_real;
1337wire [2:0] tte_pid;
1338wire [2:0] tte_page_mask;
1339wire [39:0] tte_pa;
1340wire tte_nfo;
1341wire tte_ie;
1342wire tte_cp;
1343wire tte_e;
1344wire tte_p;
1345wire tte_w;
1346wire tte_ep;
1347
1348
1349assign tlb_valid = `SPC3.lsu.tlb.array.cam.valid;
1350assign tlb_match = `SPC3.lsu.tlb.array.cam.match;
1351
1352assign tte_va = {`SPC3.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28],
1353 `SPC3.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22],
1354 `SPC3.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16],
1355 `SPC3.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13],
1356 13'b0
1357 };
1358assign tte_context = `SPC3.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO];
1359assign tte_pid = `SPC3.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO];
1360assign tte_real = `SPC3.lsu.tlb.tte_tag_1_dout[`REAL_BIT];
1361assign tte_valid = `SPC3.lsu.tlb.tte_tag_1_dout[`TTE_VALID];
1362
1363assign tte_page_mask = `SPC3.lsu.tlb.tte_page_size_mask_1;
1364
1365assign tte_pa = {`SPC3.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO],
1366 `SPC3.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO],
1367 `SPC3.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO],
1368 `SPC3.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO],
1369 13'b0
1370 };
1371assign tte_nfo = `SPC3.lsu.tlb.tte_data_1[`DATA_NFO];
1372assign tte_ie = `SPC3.lsu.tlb.tte_data_1[`DATA_IE];
1373assign tte_cp = `SPC3.lsu.tlb.tte_data_1[`DATA_CP];
1374assign tte_e = `SPC3.lsu.tlb.tte_data_1[`DATA_X];
1375assign tte_p = `SPC3.lsu.tlb.tte_data_1[`DATA_P];
1376assign tte_w = `SPC3.lsu.tlb.tte_data_1[`DATA_W];
1377assign tte_ep = 1'bx; // Does not apply for DTLB
1378
1379assign ready = `PARGS.tlb_sync_on & !`SPC3.tcu_spc_mbist_start;
1380
1381//----------------------------------------------------------
1382// Initialize state machine to idle state
1383initial begin // {
1384 #1;
1385 hwtw = 1'b0;
1386 for (i=0; i<=7; i=i+1) begin
1387 my_asi[i] = 8'b0;
1388 end
1389 @ (posedge `SPC3.l2clk);
1390
1391end // }
1392
1393//----------------------------------------------------------
1394// Must use negedge to avoid race condition
1395// tlb_entry_replace (aka entry) is created in always block using blocking assignments
1396
1397always @ (negedge (`SPC3.l2clk & ready)) begin // {
1398
1399 tstamp = `TOP.core_cycle_cnt;
1400 demap_tstamp = `TOP.core_cycle_cnt;
1401
1402 // Delay by 1 cycle to align with skip_demap
1403 demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted
1404 demap_tnum_1 <= (mycid * 8) + demap_tid;
1405 demap_1 <= demap;
1406
1407 //----------------------------------------------------------
1408 // Send I/DTLBWRITE due to demap
1409 //
1410
1411 if ((demap!=0) && (demap_1!=0)) begin // {
1412 `PR_ERROR ("tlb_sync", `ERROR,
1413 "C%0d T%0d Illegal Back to Back DTLB demap",
1414 mycid,demap_tid_1);
1415 end // }
1416
1417 if (demap_active) begin // {
1418 fifo.pop_fifo ({hwtw,mytid});
1419 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1420 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h (demap)",
1421 mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff);
1422 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
1423 mycid,demap_tid_1,demap_tnum_1,demap_tstamp);
1424 junk = $sim_send(`PLI_DTLBWRITE, demap_tnum_1,demap_tstamp,8'hff);
1425 junk = $sim_send(`PLI_SSTEP, demap_tnum_1);
1426
1427 // sstep_sent is asserted when data_in is asserted
1428 // Check to see if sstep was sent early
1429 if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // {
1430 `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture
1431 end //}
1432
1433 end //}
1434 end //}
1435
1436 //--------------------
1437 if (`PARGS.show_tlb_on & (|demap_1)) begin // {
1438 $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1);
1439
1440 if (demap_active) begin
1441 case (demap_1)
1442 4'b0001: $write ("type=real ");
1443 4'b0010: $write ("type=cntx ");
1444 4'b0100: $write ("type=page ");
1445 4'b1000: $write ("type=all ");
1446 default:
1447 `PR_ERROR ("tlb_sync", `ERROR,
1448 "Bench Problem - demap_1(%b) should be one-hot.",demap_1);
1449 endcase
1450 end
1451 else begin
1452 $write ("type=autodemap ");
1453 end
1454
1455 $display ("match=%h ts=%0d",
1456 tlb_match,demap_tstamp*`TOP.core_period);
1457
1458 for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // {
1459 if (tlb_match[cnt]==1'b1) begin // {
1460 $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d",
1461 mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period);
1462 end // }
1463 end // }
1464 //--------------------
1465 end // }
1466
1467 //----------------------------------------------------------
1468 // Send I/DHWTW due to HWTW
1469 // Send I/DTLBWRITE due to ASI write
1470
1471 // Save asi num when DTLBREAD happens.
1472 // Otherwise, hold state.
1473 // Send asi num later with DHWTW
1474 for (i=0;i<=7;i=i+1) begin // {
1475 my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i];
1476 end // }
1477
1478 // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en)
1479 // These signals will be interleaved between the threads.
1480 // Need to queue up the signals over time so they can be processed in order.
1481 // Each thread will only be doing 1 thing at a time.
1482
1483 for (i=0;i<=7;i=i+1) begin // {
1484
1485 // tlb_wr[tid] determines if the write is HWTW or TLBWRITE
1486
1487 // data_in[tid] determines which thread will write next
1488 // Use fifo to save the tids of the data_in signals in order
1489
1490 if (data_in[i]) begin // {
1491 if (tlb_wr[i]) begin // {
1492 fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]}
1493 end // }
1494 else begin // {
1495 fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]}
1496
1497 // Signal to nas_pipe to suppress SSTEP as soon we know a tlb write or demap is coming (data_in=1)
1498 // Cannot wait for wr_en because it is possible to miss an SSTEP.
1499 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)",
1500 mycid,i,((mycid * 6'h8) + i[2:0]),tstamp);
1501 `NASTOP.sstep_sent[(mycid * 6'h8) + i[2:0]] <= 1'b1; // suppress SSTEP
1502 end // }
1503 end // }
1504
1505 end // }
1506
1507 //----------------------------------------------------------
1508 // wr_en means that the write is occurring
1509 if (wr_en) begin // {
1510 fifo.pop_fifo ({hwtw,mytid});
1511 mytnum = (mycid * 8) + mytid;
1512
1513 if (hwtw) begin // {
1514 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1515 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DHWTW tid=%d ts=%0d va=%h asi=%h entry=%h",
1516 mycid,mytid,mytnum,tstamp,tte_va,my_asi[mytid],entry);
1517 junk = $sim_send(`PLI_DHWTW, mytnum,tstamp,tte_va,my_asi[mytid],entry);
1518
1519 end //}
1520 end // }
1521 else begin // {
1522 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1523 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h",
1524 mycid,mytid,mytnum,tstamp,entry);
1525 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
1526 mycid,mytid,mytnum,tstamp);
1527 junk = $sim_send(`PLI_DTLBWRITE, mytnum,tstamp,entry);
1528 junk = $sim_send(`PLI_SSTEP, mytnum);
1529
1530 // Check to see if sstep was sent early
1531 if (`NASTOP.sstep_sent[mytnum]==1) begin // {
1532 `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture
1533 end //}
1534
1535 end //}
1536 end // }
1537
1538 //--------------------
1539 if (`PARGS.show_tlb_on) begin // {
1540 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
1541
1542 if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va);
1543 else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va);
1544
1545 case (tte_page_mask)
1546 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d",
1547 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
1548 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d",
1549 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
1550 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d",
1551 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
1552 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d",
1553 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
1554 endcase
1555
1556 if (hwtw) $display (" (hwtw)");
1557 else $display ("");
1558
1559 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
1560
1561 $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d",
1562 tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period);
1563 end // }
1564 //--------------------
1565
1566 end // }
1567
1568end // always}
1569
1570//----------------------------------------------------------
1571`endif
1572endmodule
1573
1574`endif
1575`ifdef CORE_4
1576
1577module dtlb_wr_c4 ();
1578`ifndef GATESIM
1579
1580`include "tlb_sync.vh"
1581`include "nas.vh"
1582parameter NUM_TLB=128;
1583
1584wire [7:0] data_in;
1585wire [7:0] tlb_wr;
1586wire wr_en;
1587wire [7:0] entry;
1588wire [7:0] asi_num;
1589wire asi_enable0; // 1 per thread group
1590wire asi_enable1;
1591wire [7:0] store_asi; // 1 per thread
1592wire [3:0] demap;
1593reg [3:0] demap_1;
1594wire demap_page;
1595wire demap_context;
1596wire demap_real;
1597wire demap_all;
1598wire skip_demap;
1599wire demap_active;
1600wire auto_demap;
1601wire [2:0] demap_tid;
1602reg [2:0] demap_tid_1;
1603reg [5:0] demap_tnum_1;
1604
1605reg [(`TS_WIDTH-1):0] tstamp;
1606reg hwtw;
1607reg [7:0] my_asi [0:7]; // 1 asi number stored per thread
1608reg [(`TS_WIDTH-1):0] demap_tstamp;
1609
1610reg [2:0] mytid;
1611reg [5:0] mytnum;
1612wire [2:0] mycid;
1613integer junk;
1614integer i;
1615reg [7:0] cnt;
1616wire ready;
1617
1618assign mycid = 4;
1619
1620`ifdef DEBUG_TLB
1621 wire [7:0] my_asi0 = my_asi[0];
1622 wire [7:0] my_asi1 = my_asi[1];
1623 wire [7:0] my_asi2 = my_asi[2];
1624 wire [7:0] my_asi3 = my_asi[3];
1625 wire [7:0] my_asi4 = my_asi[4];
1626 wire [7:0] my_asi5 = my_asi[5];
1627 wire [7:0] my_asi6 = my_asi[6];
1628 wire [7:0] my_asi7 = my_asi[7];
1629`endif
1630
1631//----------------------------------------------------------
1632// Instantiate fifo - 1 entry per thread
1633fifo fifo ();
1634// Define fifo parameters
1635defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]}
1636defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection
1637defparam fifo.PTR_BITS = 4;
1638
1639//----------------------------------------------------------
1640// DUT probes
1641
1642assign data_in = `SPC4.mmu.asi.wrote_dtlb;
1643assign tlb_wr = `SPC4.mmu_reload_done;
1644assign wr_en = `SPC4.lsu.tlb.tlb_wr_1_in_dout;
1645
1646assign entry = `SPC4.lsu.tlb.rw_index_1[6:0];
1647
1648assign asi_num = `PROBES4.asi_num;
1649assign asi_enable0 = `PROBES4.tlb_rd_vld_b &
1650 !`PROBES4.tlb_bypass_b &
1651 `SPC4.tlu.fls0.lsu_inst_b;
1652assign asi_enable1 = `PROBES4.tlb_rd_vld_b &
1653 !`PROBES4.tlb_bypass_b &
1654 `SPC4.tlu.fls1.lsu_inst_b;
1655
1656assign store_asi[3:0] = asi_enable0 ? `PROBES4.select_pc_b[3:0] : 4'b0;
1657assign store_asi[7:4] = asi_enable1 ? `PROBES4.select_pc_b[7:4] : 4'b0;
1658
1659assign demap_page = `SPC4.lsu.tlc_demap & ~(demap_context | demap_real | demap_all);
1660assign demap_context = `SPC4.lsu.tlc_demap_context;
1661assign demap_real = `SPC4.lsu.tlc_demap_real;
1662assign demap_all = `SPC4.lsu.tlc_demap_all;
1663assign demap = {demap_all,demap_page,demap_context,demap_real};
1664assign skip_demap =`SPC4.lsu.tlc_wr_u_en;
1665assign demap_tid = `SPC4.lsu.tld.tte1[37:35];
1666
1667// if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS
1668assign demap_active = |demap_1 && !skip_demap;
1669assign auto_demap = |demap_1 && skip_demap;
1670
1671//---------------------
1672// Probes for debugging
1673
1674// defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl
1675
1676// n2_tlb_tl_128x59_cam.sv
1677
1678`define CNTX1_HI 65
1679`define CNTX1_LO 53
1680`define PID_HI 52
1681`define PID_LO 50
1682`define REAL_BIT 49
1683`define VA_47 48
1684`define VA_28 29
1685`define VA_27 28
1686`define VA_22 23
1687`define TTE_VALID 22
1688`define VA_21 21
1689`define VA_16 16
1690`define VA_15 15
1691`define VA_13 13
1692`define CNTX0_HI 12
1693`define CNTX0_LO 0
1694
1695// n2_tlb_tl_128x59_ram.sv
1696
1697`define DATA_PARITY 36
1698`define DATA_PA_39_28_HI 35
1699`define DATA_PA_39_28_LO 24
1700`define DATA_PA_27_22_HI 23
1701`define DATA_PA_27_22_LO 18
1702`define DATA_VA_27_22_V 17
1703`define DATA_PA_21_16_HI 16
1704`define DATA_PA_21_16_LO 11
1705`define DATA_VA_21_16_V 10
1706`define DATA_PA_15_13_HI 9
1707`define DATA_PA_15_13_LO 7
1708`define DATA_VA_15_13_V 6
1709`define DATA_NFO 5
1710`define DATA_IE 4
1711`define DATA_CP 3
1712`define DATA_X 2
1713`define DATA_P 1
1714`define DATA_W 0
1715
1716wire [(NUM_TLB-1):0] tlb_valid;
1717wire [(NUM_TLB-1):0] tlb_match;
1718wire tte_valid;
1719wire [47:0] tte_va;
1720wire [12:0] tte_context;
1721wire tte_real;
1722wire [2:0] tte_pid;
1723wire [2:0] tte_page_mask;
1724wire [39:0] tte_pa;
1725wire tte_nfo;
1726wire tte_ie;
1727wire tte_cp;
1728wire tte_e;
1729wire tte_p;
1730wire tte_w;
1731wire tte_ep;
1732
1733
1734assign tlb_valid = `SPC4.lsu.tlb.array.cam.valid;
1735assign tlb_match = `SPC4.lsu.tlb.array.cam.match;
1736
1737assign tte_va = {`SPC4.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28],
1738 `SPC4.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22],
1739 `SPC4.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16],
1740 `SPC4.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13],
1741 13'b0
1742 };
1743assign tte_context = `SPC4.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO];
1744assign tte_pid = `SPC4.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO];
1745assign tte_real = `SPC4.lsu.tlb.tte_tag_1_dout[`REAL_BIT];
1746assign tte_valid = `SPC4.lsu.tlb.tte_tag_1_dout[`TTE_VALID];
1747
1748assign tte_page_mask = `SPC4.lsu.tlb.tte_page_size_mask_1;
1749
1750assign tte_pa = {`SPC4.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO],
1751 `SPC4.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO],
1752 `SPC4.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO],
1753 `SPC4.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO],
1754 13'b0
1755 };
1756assign tte_nfo = `SPC4.lsu.tlb.tte_data_1[`DATA_NFO];
1757assign tte_ie = `SPC4.lsu.tlb.tte_data_1[`DATA_IE];
1758assign tte_cp = `SPC4.lsu.tlb.tte_data_1[`DATA_CP];
1759assign tte_e = `SPC4.lsu.tlb.tte_data_1[`DATA_X];
1760assign tte_p = `SPC4.lsu.tlb.tte_data_1[`DATA_P];
1761assign tte_w = `SPC4.lsu.tlb.tte_data_1[`DATA_W];
1762assign tte_ep = 1'bx; // Does not apply for DTLB
1763
1764assign ready = `PARGS.tlb_sync_on & !`SPC4.tcu_spc_mbist_start;
1765
1766//----------------------------------------------------------
1767// Initialize state machine to idle state
1768initial begin // {
1769 #1;
1770 hwtw = 1'b0;
1771 for (i=0; i<=7; i=i+1) begin
1772 my_asi[i] = 8'b0;
1773 end
1774 @ (posedge `SPC4.l2clk);
1775
1776end // }
1777
1778//----------------------------------------------------------
1779// Must use negedge to avoid race condition
1780// tlb_entry_replace (aka entry) is created in always block using blocking assignments
1781
1782always @ (negedge (`SPC4.l2clk & ready)) begin // {
1783
1784 tstamp = `TOP.core_cycle_cnt;
1785 demap_tstamp = `TOP.core_cycle_cnt;
1786
1787 // Delay by 1 cycle to align with skip_demap
1788 demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted
1789 demap_tnum_1 <= (mycid * 8) + demap_tid;
1790 demap_1 <= demap;
1791
1792 //----------------------------------------------------------
1793 // Send I/DTLBWRITE due to demap
1794 //
1795
1796 if ((demap!=0) && (demap_1!=0)) begin // {
1797 `PR_ERROR ("tlb_sync", `ERROR,
1798 "C%0d T%0d Illegal Back to Back DTLB demap",
1799 mycid,demap_tid_1);
1800 end // }
1801
1802 if (demap_active) begin // {
1803 fifo.pop_fifo ({hwtw,mytid});
1804 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1805 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h (demap)",
1806 mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff);
1807 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
1808 mycid,demap_tid_1,demap_tnum_1,demap_tstamp);
1809 junk = $sim_send(`PLI_DTLBWRITE, demap_tnum_1,demap_tstamp,8'hff);
1810 junk = $sim_send(`PLI_SSTEP, demap_tnum_1);
1811
1812 // sstep_sent is asserted when data_in is asserted
1813 // Check to see if sstep was sent early
1814 if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // {
1815 `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture
1816 end //}
1817
1818 end //}
1819 end //}
1820
1821 //--------------------
1822 if (`PARGS.show_tlb_on & (|demap_1)) begin // {
1823 $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1);
1824
1825 if (demap_active) begin
1826 case (demap_1)
1827 4'b0001: $write ("type=real ");
1828 4'b0010: $write ("type=cntx ");
1829 4'b0100: $write ("type=page ");
1830 4'b1000: $write ("type=all ");
1831 default:
1832 `PR_ERROR ("tlb_sync", `ERROR,
1833 "Bench Problem - demap_1(%b) should be one-hot.",demap_1);
1834 endcase
1835 end
1836 else begin
1837 $write ("type=autodemap ");
1838 end
1839
1840 $display ("match=%h ts=%0d",
1841 tlb_match,demap_tstamp*`TOP.core_period);
1842
1843 for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // {
1844 if (tlb_match[cnt]==1'b1) begin // {
1845 $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d",
1846 mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period);
1847 end // }
1848 end // }
1849 //--------------------
1850 end // }
1851
1852 //----------------------------------------------------------
1853 // Send I/DHWTW due to HWTW
1854 // Send I/DTLBWRITE due to ASI write
1855
1856 // Save asi num when DTLBREAD happens.
1857 // Otherwise, hold state.
1858 // Send asi num later with DHWTW
1859 for (i=0;i<=7;i=i+1) begin // {
1860 my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i];
1861 end // }
1862
1863 // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en)
1864 // These signals will be interleaved between the threads.
1865 // Need to queue up the signals over time so they can be processed in order.
1866 // Each thread will only be doing 1 thing at a time.
1867
1868 for (i=0;i<=7;i=i+1) begin // {
1869
1870 // tlb_wr[tid] determines if the write is HWTW or TLBWRITE
1871
1872 // data_in[tid] determines which thread will write next
1873 // Use fifo to save the tids of the data_in signals in order
1874
1875 if (data_in[i]) begin // {
1876 if (tlb_wr[i]) begin // {
1877 fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]}
1878 end // }
1879 else begin // {
1880 fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]}
1881
1882 // Signal to nas_pipe to suppress SSTEP as soon we know a tlb write or demap is coming (data_in=1)
1883 // Cannot wait for wr_en because it is possible to miss an SSTEP.
1884 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)",
1885 mycid,i,((mycid * 6'h8) + i[2:0]),tstamp);
1886 `NASTOP.sstep_sent[(mycid * 6'h8) + i[2:0]] <= 1'b1; // suppress SSTEP
1887 end // }
1888 end // }
1889
1890 end // }
1891
1892 //----------------------------------------------------------
1893 // wr_en means that the write is occurring
1894 if (wr_en) begin // {
1895 fifo.pop_fifo ({hwtw,mytid});
1896 mytnum = (mycid * 8) + mytid;
1897
1898 if (hwtw) begin // {
1899 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1900 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DHWTW tid=%d ts=%0d va=%h asi=%h entry=%h",
1901 mycid,mytid,mytnum,tstamp,tte_va,my_asi[mytid],entry);
1902 junk = $sim_send(`PLI_DHWTW, mytnum,tstamp,tte_va,my_asi[mytid],entry);
1903
1904 end //}
1905 end // }
1906 else begin // {
1907 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
1908 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h",
1909 mycid,mytid,mytnum,tstamp,entry);
1910 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
1911 mycid,mytid,mytnum,tstamp);
1912 junk = $sim_send(`PLI_DTLBWRITE, mytnum,tstamp,entry);
1913 junk = $sim_send(`PLI_SSTEP, mytnum);
1914
1915 // Check to see if sstep was sent early
1916 if (`NASTOP.sstep_sent[mytnum]==1) begin // {
1917 `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture
1918 end //}
1919
1920 end //}
1921 end // }
1922
1923 //--------------------
1924 if (`PARGS.show_tlb_on) begin // {
1925 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
1926
1927 if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va);
1928 else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va);
1929
1930 case (tte_page_mask)
1931 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d",
1932 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
1933 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d",
1934 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
1935 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d",
1936 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
1937 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d",
1938 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
1939 endcase
1940
1941 if (hwtw) $display (" (hwtw)");
1942 else $display ("");
1943
1944 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
1945
1946 $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d",
1947 tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period);
1948 end // }
1949 //--------------------
1950
1951 end // }
1952
1953end // always}
1954
1955//----------------------------------------------------------
1956`endif
1957endmodule
1958
1959`endif
1960`ifdef CORE_5
1961
1962module dtlb_wr_c5 ();
1963`ifndef GATESIM
1964
1965`include "tlb_sync.vh"
1966`include "nas.vh"
1967parameter NUM_TLB=128;
1968
1969wire [7:0] data_in;
1970wire [7:0] tlb_wr;
1971wire wr_en;
1972wire [7:0] entry;
1973wire [7:0] asi_num;
1974wire asi_enable0; // 1 per thread group
1975wire asi_enable1;
1976wire [7:0] store_asi; // 1 per thread
1977wire [3:0] demap;
1978reg [3:0] demap_1;
1979wire demap_page;
1980wire demap_context;
1981wire demap_real;
1982wire demap_all;
1983wire skip_demap;
1984wire demap_active;
1985wire auto_demap;
1986wire [2:0] demap_tid;
1987reg [2:0] demap_tid_1;
1988reg [5:0] demap_tnum_1;
1989
1990reg [(`TS_WIDTH-1):0] tstamp;
1991reg hwtw;
1992reg [7:0] my_asi [0:7]; // 1 asi number stored per thread
1993reg [(`TS_WIDTH-1):0] demap_tstamp;
1994
1995reg [2:0] mytid;
1996reg [5:0] mytnum;
1997wire [2:0] mycid;
1998integer junk;
1999integer i;
2000reg [7:0] cnt;
2001wire ready;
2002
2003assign mycid = 5;
2004
2005`ifdef DEBUG_TLB
2006 wire [7:0] my_asi0 = my_asi[0];
2007 wire [7:0] my_asi1 = my_asi[1];
2008 wire [7:0] my_asi2 = my_asi[2];
2009 wire [7:0] my_asi3 = my_asi[3];
2010 wire [7:0] my_asi4 = my_asi[4];
2011 wire [7:0] my_asi5 = my_asi[5];
2012 wire [7:0] my_asi6 = my_asi[6];
2013 wire [7:0] my_asi7 = my_asi[7];
2014`endif
2015
2016//----------------------------------------------------------
2017// Instantiate fifo - 1 entry per thread
2018fifo fifo ();
2019// Define fifo parameters
2020defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]}
2021defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection
2022defparam fifo.PTR_BITS = 4;
2023
2024//----------------------------------------------------------
2025// DUT probes
2026
2027assign data_in = `SPC5.mmu.asi.wrote_dtlb;
2028assign tlb_wr = `SPC5.mmu_reload_done;
2029assign wr_en = `SPC5.lsu.tlb.tlb_wr_1_in_dout;
2030
2031assign entry = `SPC5.lsu.tlb.rw_index_1[6:0];
2032
2033assign asi_num = `PROBES5.asi_num;
2034assign asi_enable0 = `PROBES5.tlb_rd_vld_b &
2035 !`PROBES5.tlb_bypass_b &
2036 `SPC5.tlu.fls0.lsu_inst_b;
2037assign asi_enable1 = `PROBES5.tlb_rd_vld_b &
2038 !`PROBES5.tlb_bypass_b &
2039 `SPC5.tlu.fls1.lsu_inst_b;
2040
2041assign store_asi[3:0] = asi_enable0 ? `PROBES5.select_pc_b[3:0] : 4'b0;
2042assign store_asi[7:4] = asi_enable1 ? `PROBES5.select_pc_b[7:4] : 4'b0;
2043
2044assign demap_page = `SPC5.lsu.tlc_demap & ~(demap_context | demap_real | demap_all);
2045assign demap_context = `SPC5.lsu.tlc_demap_context;
2046assign demap_real = `SPC5.lsu.tlc_demap_real;
2047assign demap_all = `SPC5.lsu.tlc_demap_all;
2048assign demap = {demap_all,demap_page,demap_context,demap_real};
2049assign skip_demap =`SPC5.lsu.tlc_wr_u_en;
2050assign demap_tid = `SPC5.lsu.tld.tte1[37:35];
2051
2052// if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS
2053assign demap_active = |demap_1 && !skip_demap;
2054assign auto_demap = |demap_1 && skip_demap;
2055
2056//---------------------
2057// Probes for debugging
2058
2059// defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl
2060
2061// n2_tlb_tl_128x59_cam.sv
2062
2063`define CNTX1_HI 65
2064`define CNTX1_LO 53
2065`define PID_HI 52
2066`define PID_LO 50
2067`define REAL_BIT 49
2068`define VA_47 48
2069`define VA_28 29
2070`define VA_27 28
2071`define VA_22 23
2072`define TTE_VALID 22
2073`define VA_21 21
2074`define VA_16 16
2075`define VA_15 15
2076`define VA_13 13
2077`define CNTX0_HI 12
2078`define CNTX0_LO 0
2079
2080// n2_tlb_tl_128x59_ram.sv
2081
2082`define DATA_PARITY 36
2083`define DATA_PA_39_28_HI 35
2084`define DATA_PA_39_28_LO 24
2085`define DATA_PA_27_22_HI 23
2086`define DATA_PA_27_22_LO 18
2087`define DATA_VA_27_22_V 17
2088`define DATA_PA_21_16_HI 16
2089`define DATA_PA_21_16_LO 11
2090`define DATA_VA_21_16_V 10
2091`define DATA_PA_15_13_HI 9
2092`define DATA_PA_15_13_LO 7
2093`define DATA_VA_15_13_V 6
2094`define DATA_NFO 5
2095`define DATA_IE 4
2096`define DATA_CP 3
2097`define DATA_X 2
2098`define DATA_P 1
2099`define DATA_W 0
2100
2101wire [(NUM_TLB-1):0] tlb_valid;
2102wire [(NUM_TLB-1):0] tlb_match;
2103wire tte_valid;
2104wire [47:0] tte_va;
2105wire [12:0] tte_context;
2106wire tte_real;
2107wire [2:0] tte_pid;
2108wire [2:0] tte_page_mask;
2109wire [39:0] tte_pa;
2110wire tte_nfo;
2111wire tte_ie;
2112wire tte_cp;
2113wire tte_e;
2114wire tte_p;
2115wire tte_w;
2116wire tte_ep;
2117
2118
2119assign tlb_valid = `SPC5.lsu.tlb.array.cam.valid;
2120assign tlb_match = `SPC5.lsu.tlb.array.cam.match;
2121
2122assign tte_va = {`SPC5.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28],
2123 `SPC5.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22],
2124 `SPC5.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16],
2125 `SPC5.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13],
2126 13'b0
2127 };
2128assign tte_context = `SPC5.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO];
2129assign tte_pid = `SPC5.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO];
2130assign tte_real = `SPC5.lsu.tlb.tte_tag_1_dout[`REAL_BIT];
2131assign tte_valid = `SPC5.lsu.tlb.tte_tag_1_dout[`TTE_VALID];
2132
2133assign tte_page_mask = `SPC5.lsu.tlb.tte_page_size_mask_1;
2134
2135assign tte_pa = {`SPC5.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO],
2136 `SPC5.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO],
2137 `SPC5.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO],
2138 `SPC5.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO],
2139 13'b0
2140 };
2141assign tte_nfo = `SPC5.lsu.tlb.tte_data_1[`DATA_NFO];
2142assign tte_ie = `SPC5.lsu.tlb.tte_data_1[`DATA_IE];
2143assign tte_cp = `SPC5.lsu.tlb.tte_data_1[`DATA_CP];
2144assign tte_e = `SPC5.lsu.tlb.tte_data_1[`DATA_X];
2145assign tte_p = `SPC5.lsu.tlb.tte_data_1[`DATA_P];
2146assign tte_w = `SPC5.lsu.tlb.tte_data_1[`DATA_W];
2147assign tte_ep = 1'bx; // Does not apply for DTLB
2148
2149assign ready = `PARGS.tlb_sync_on & !`SPC5.tcu_spc_mbist_start;
2150
2151//----------------------------------------------------------
2152// Initialize state machine to idle state
2153initial begin // {
2154 #1;
2155 hwtw = 1'b0;
2156 for (i=0; i<=7; i=i+1) begin
2157 my_asi[i] = 8'b0;
2158 end
2159 @ (posedge `SPC5.l2clk);
2160
2161end // }
2162
2163//----------------------------------------------------------
2164// Must use negedge to avoid race condition
2165// tlb_entry_replace (aka entry) is created in always block using blocking assignments
2166
2167always @ (negedge (`SPC5.l2clk & ready)) begin // {
2168
2169 tstamp = `TOP.core_cycle_cnt;
2170 demap_tstamp = `TOP.core_cycle_cnt;
2171
2172 // Delay by 1 cycle to align with skip_demap
2173 demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted
2174 demap_tnum_1 <= (mycid * 8) + demap_tid;
2175 demap_1 <= demap;
2176
2177 //----------------------------------------------------------
2178 // Send I/DTLBWRITE due to demap
2179 //
2180
2181 if ((demap!=0) && (demap_1!=0)) begin // {
2182 `PR_ERROR ("tlb_sync", `ERROR,
2183 "C%0d T%0d Illegal Back to Back DTLB demap",
2184 mycid,demap_tid_1);
2185 end // }
2186
2187 if (demap_active) begin // {
2188 fifo.pop_fifo ({hwtw,mytid});
2189 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2190 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h (demap)",
2191 mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff);
2192 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
2193 mycid,demap_tid_1,demap_tnum_1,demap_tstamp);
2194 junk = $sim_send(`PLI_DTLBWRITE, demap_tnum_1,demap_tstamp,8'hff);
2195 junk = $sim_send(`PLI_SSTEP, demap_tnum_1);
2196
2197 // sstep_sent is asserted when data_in is asserted
2198 // Check to see if sstep was sent early
2199 if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // {
2200 `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture
2201 end //}
2202
2203 end //}
2204 end //}
2205
2206 //--------------------
2207 if (`PARGS.show_tlb_on & (|demap_1)) begin // {
2208 $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1);
2209
2210 if (demap_active) begin
2211 case (demap_1)
2212 4'b0001: $write ("type=real ");
2213 4'b0010: $write ("type=cntx ");
2214 4'b0100: $write ("type=page ");
2215 4'b1000: $write ("type=all ");
2216 default:
2217 `PR_ERROR ("tlb_sync", `ERROR,
2218 "Bench Problem - demap_1(%b) should be one-hot.",demap_1);
2219 endcase
2220 end
2221 else begin
2222 $write ("type=autodemap ");
2223 end
2224
2225 $display ("match=%h ts=%0d",
2226 tlb_match,demap_tstamp*`TOP.core_period);
2227
2228 for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // {
2229 if (tlb_match[cnt]==1'b1) begin // {
2230 $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d",
2231 mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period);
2232 end // }
2233 end // }
2234 //--------------------
2235 end // }
2236
2237 //----------------------------------------------------------
2238 // Send I/DHWTW due to HWTW
2239 // Send I/DTLBWRITE due to ASI write
2240
2241 // Save asi num when DTLBREAD happens.
2242 // Otherwise, hold state.
2243 // Send asi num later with DHWTW
2244 for (i=0;i<=7;i=i+1) begin // {
2245 my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i];
2246 end // }
2247
2248 // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en)
2249 // These signals will be interleaved between the threads.
2250 // Need to queue up the signals over time so they can be processed in order.
2251 // Each thread will only be doing 1 thing at a time.
2252
2253 for (i=0;i<=7;i=i+1) begin // {
2254
2255 // tlb_wr[tid] determines if the write is HWTW or TLBWRITE
2256
2257 // data_in[tid] determines which thread will write next
2258 // Use fifo to save the tids of the data_in signals in order
2259
2260 if (data_in[i]) begin // {
2261 if (tlb_wr[i]) begin // {
2262 fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]}
2263 end // }
2264 else begin // {
2265 fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]}
2266
2267 // Signal to nas_pipe to suppress SSTEP as soon we know a tlb write or demap is coming (data_in=1)
2268 // Cannot wait for wr_en because it is possible to miss an SSTEP.
2269 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)",
2270 mycid,i,((mycid * 6'h8) + i[2:0]),tstamp);
2271 `NASTOP.sstep_sent[(mycid * 6'h8) + i[2:0]] <= 1'b1; // suppress SSTEP
2272 end // }
2273 end // }
2274
2275 end // }
2276
2277 //----------------------------------------------------------
2278 // wr_en means that the write is occurring
2279 if (wr_en) begin // {
2280 fifo.pop_fifo ({hwtw,mytid});
2281 mytnum = (mycid * 8) + mytid;
2282
2283 if (hwtw) begin // {
2284 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2285 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DHWTW tid=%d ts=%0d va=%h asi=%h entry=%h",
2286 mycid,mytid,mytnum,tstamp,tte_va,my_asi[mytid],entry);
2287 junk = $sim_send(`PLI_DHWTW, mytnum,tstamp,tte_va,my_asi[mytid],entry);
2288
2289 end //}
2290 end // }
2291 else begin // {
2292 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2293 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h",
2294 mycid,mytid,mytnum,tstamp,entry);
2295 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
2296 mycid,mytid,mytnum,tstamp);
2297 junk = $sim_send(`PLI_DTLBWRITE, mytnum,tstamp,entry);
2298 junk = $sim_send(`PLI_SSTEP, mytnum);
2299
2300 // Check to see if sstep was sent early
2301 if (`NASTOP.sstep_sent[mytnum]==1) begin // {
2302 `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture
2303 end //}
2304
2305 end //}
2306 end // }
2307
2308 //--------------------
2309 if (`PARGS.show_tlb_on) begin // {
2310 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
2311
2312 if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va);
2313 else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va);
2314
2315 case (tte_page_mask)
2316 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d",
2317 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
2318 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d",
2319 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
2320 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d",
2321 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
2322 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d",
2323 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
2324 endcase
2325
2326 if (hwtw) $display (" (hwtw)");
2327 else $display ("");
2328
2329 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
2330
2331 $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d",
2332 tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period);
2333 end // }
2334 //--------------------
2335
2336 end // }
2337
2338end // always}
2339
2340//----------------------------------------------------------
2341`endif
2342endmodule
2343
2344`endif
2345`ifdef CORE_6
2346
2347module dtlb_wr_c6 ();
2348`ifndef GATESIM
2349
2350`include "tlb_sync.vh"
2351`include "nas.vh"
2352parameter NUM_TLB=128;
2353
2354wire [7:0] data_in;
2355wire [7:0] tlb_wr;
2356wire wr_en;
2357wire [7:0] entry;
2358wire [7:0] asi_num;
2359wire asi_enable0; // 1 per thread group
2360wire asi_enable1;
2361wire [7:0] store_asi; // 1 per thread
2362wire [3:0] demap;
2363reg [3:0] demap_1;
2364wire demap_page;
2365wire demap_context;
2366wire demap_real;
2367wire demap_all;
2368wire skip_demap;
2369wire demap_active;
2370wire auto_demap;
2371wire [2:0] demap_tid;
2372reg [2:0] demap_tid_1;
2373reg [5:0] demap_tnum_1;
2374
2375reg [(`TS_WIDTH-1):0] tstamp;
2376reg hwtw;
2377reg [7:0] my_asi [0:7]; // 1 asi number stored per thread
2378reg [(`TS_WIDTH-1):0] demap_tstamp;
2379
2380reg [2:0] mytid;
2381reg [5:0] mytnum;
2382wire [2:0] mycid;
2383integer junk;
2384integer i;
2385reg [7:0] cnt;
2386wire ready;
2387
2388assign mycid = 6;
2389
2390`ifdef DEBUG_TLB
2391 wire [7:0] my_asi0 = my_asi[0];
2392 wire [7:0] my_asi1 = my_asi[1];
2393 wire [7:0] my_asi2 = my_asi[2];
2394 wire [7:0] my_asi3 = my_asi[3];
2395 wire [7:0] my_asi4 = my_asi[4];
2396 wire [7:0] my_asi5 = my_asi[5];
2397 wire [7:0] my_asi6 = my_asi[6];
2398 wire [7:0] my_asi7 = my_asi[7];
2399`endif
2400
2401//----------------------------------------------------------
2402// Instantiate fifo - 1 entry per thread
2403fifo fifo ();
2404// Define fifo parameters
2405defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]}
2406defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection
2407defparam fifo.PTR_BITS = 4;
2408
2409//----------------------------------------------------------
2410// DUT probes
2411
2412assign data_in = `SPC6.mmu.asi.wrote_dtlb;
2413assign tlb_wr = `SPC6.mmu_reload_done;
2414assign wr_en = `SPC6.lsu.tlb.tlb_wr_1_in_dout;
2415
2416assign entry = `SPC6.lsu.tlb.rw_index_1[6:0];
2417
2418assign asi_num = `PROBES6.asi_num;
2419assign asi_enable0 = `PROBES6.tlb_rd_vld_b &
2420 !`PROBES6.tlb_bypass_b &
2421 `SPC6.tlu.fls0.lsu_inst_b;
2422assign asi_enable1 = `PROBES6.tlb_rd_vld_b &
2423 !`PROBES6.tlb_bypass_b &
2424 `SPC6.tlu.fls1.lsu_inst_b;
2425
2426assign store_asi[3:0] = asi_enable0 ? `PROBES6.select_pc_b[3:0] : 4'b0;
2427assign store_asi[7:4] = asi_enable1 ? `PROBES6.select_pc_b[7:4] : 4'b0;
2428
2429assign demap_page = `SPC6.lsu.tlc_demap & ~(demap_context | demap_real | demap_all);
2430assign demap_context = `SPC6.lsu.tlc_demap_context;
2431assign demap_real = `SPC6.lsu.tlc_demap_real;
2432assign demap_all = `SPC6.lsu.tlc_demap_all;
2433assign demap = {demap_all,demap_page,demap_context,demap_real};
2434assign skip_demap =`SPC6.lsu.tlc_wr_u_en;
2435assign demap_tid = `SPC6.lsu.tld.tte1[37:35];
2436
2437// if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS
2438assign demap_active = |demap_1 && !skip_demap;
2439assign auto_demap = |demap_1 && skip_demap;
2440
2441//---------------------
2442// Probes for debugging
2443
2444// defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl
2445
2446// n2_tlb_tl_128x59_cam.sv
2447
2448`define CNTX1_HI 65
2449`define CNTX1_LO 53
2450`define PID_HI 52
2451`define PID_LO 50
2452`define REAL_BIT 49
2453`define VA_47 48
2454`define VA_28 29
2455`define VA_27 28
2456`define VA_22 23
2457`define TTE_VALID 22
2458`define VA_21 21
2459`define VA_16 16
2460`define VA_15 15
2461`define VA_13 13
2462`define CNTX0_HI 12
2463`define CNTX0_LO 0
2464
2465// n2_tlb_tl_128x59_ram.sv
2466
2467`define DATA_PARITY 36
2468`define DATA_PA_39_28_HI 35
2469`define DATA_PA_39_28_LO 24
2470`define DATA_PA_27_22_HI 23
2471`define DATA_PA_27_22_LO 18
2472`define DATA_VA_27_22_V 17
2473`define DATA_PA_21_16_HI 16
2474`define DATA_PA_21_16_LO 11
2475`define DATA_VA_21_16_V 10
2476`define DATA_PA_15_13_HI 9
2477`define DATA_PA_15_13_LO 7
2478`define DATA_VA_15_13_V 6
2479`define DATA_NFO 5
2480`define DATA_IE 4
2481`define DATA_CP 3
2482`define DATA_X 2
2483`define DATA_P 1
2484`define DATA_W 0
2485
2486wire [(NUM_TLB-1):0] tlb_valid;
2487wire [(NUM_TLB-1):0] tlb_match;
2488wire tte_valid;
2489wire [47:0] tte_va;
2490wire [12:0] tte_context;
2491wire tte_real;
2492wire [2:0] tte_pid;
2493wire [2:0] tte_page_mask;
2494wire [39:0] tte_pa;
2495wire tte_nfo;
2496wire tte_ie;
2497wire tte_cp;
2498wire tte_e;
2499wire tte_p;
2500wire tte_w;
2501wire tte_ep;
2502
2503
2504assign tlb_valid = `SPC6.lsu.tlb.array.cam.valid;
2505assign tlb_match = `SPC6.lsu.tlb.array.cam.match;
2506
2507assign tte_va = {`SPC6.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28],
2508 `SPC6.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22],
2509 `SPC6.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16],
2510 `SPC6.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13],
2511 13'b0
2512 };
2513assign tte_context = `SPC6.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO];
2514assign tte_pid = `SPC6.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO];
2515assign tte_real = `SPC6.lsu.tlb.tte_tag_1_dout[`REAL_BIT];
2516assign tte_valid = `SPC6.lsu.tlb.tte_tag_1_dout[`TTE_VALID];
2517
2518assign tte_page_mask = `SPC6.lsu.tlb.tte_page_size_mask_1;
2519
2520assign tte_pa = {`SPC6.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO],
2521 `SPC6.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO],
2522 `SPC6.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO],
2523 `SPC6.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO],
2524 13'b0
2525 };
2526assign tte_nfo = `SPC6.lsu.tlb.tte_data_1[`DATA_NFO];
2527assign tte_ie = `SPC6.lsu.tlb.tte_data_1[`DATA_IE];
2528assign tte_cp = `SPC6.lsu.tlb.tte_data_1[`DATA_CP];
2529assign tte_e = `SPC6.lsu.tlb.tte_data_1[`DATA_X];
2530assign tte_p = `SPC6.lsu.tlb.tte_data_1[`DATA_P];
2531assign tte_w = `SPC6.lsu.tlb.tte_data_1[`DATA_W];
2532assign tte_ep = 1'bx; // Does not apply for DTLB
2533
2534assign ready = `PARGS.tlb_sync_on & !`SPC6.tcu_spc_mbist_start;
2535
2536//----------------------------------------------------------
2537// Initialize state machine to idle state
2538initial begin // {
2539 #1;
2540 hwtw = 1'b0;
2541 for (i=0; i<=7; i=i+1) begin
2542 my_asi[i] = 8'b0;
2543 end
2544 @ (posedge `SPC6.l2clk);
2545
2546end // }
2547
2548//----------------------------------------------------------
2549// Must use negedge to avoid race condition
2550// tlb_entry_replace (aka entry) is created in always block using blocking assignments
2551
2552always @ (negedge (`SPC6.l2clk & ready)) begin // {
2553
2554 tstamp = `TOP.core_cycle_cnt;
2555 demap_tstamp = `TOP.core_cycle_cnt;
2556
2557 // Delay by 1 cycle to align with skip_demap
2558 demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted
2559 demap_tnum_1 <= (mycid * 8) + demap_tid;
2560 demap_1 <= demap;
2561
2562 //----------------------------------------------------------
2563 // Send I/DTLBWRITE due to demap
2564 //
2565
2566 if ((demap!=0) && (demap_1!=0)) begin // {
2567 `PR_ERROR ("tlb_sync", `ERROR,
2568 "C%0d T%0d Illegal Back to Back DTLB demap",
2569 mycid,demap_tid_1);
2570 end // }
2571
2572 if (demap_active) begin // {
2573 fifo.pop_fifo ({hwtw,mytid});
2574 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2575 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h (demap)",
2576 mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff);
2577 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
2578 mycid,demap_tid_1,demap_tnum_1,demap_tstamp);
2579 junk = $sim_send(`PLI_DTLBWRITE, demap_tnum_1,demap_tstamp,8'hff);
2580 junk = $sim_send(`PLI_SSTEP, demap_tnum_1);
2581
2582 // sstep_sent is asserted when data_in is asserted
2583 // Check to see if sstep was sent early
2584 if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // {
2585 `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture
2586 end //}
2587
2588 end //}
2589 end //}
2590
2591 //--------------------
2592 if (`PARGS.show_tlb_on & (|demap_1)) begin // {
2593 $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1);
2594
2595 if (demap_active) begin
2596 case (demap_1)
2597 4'b0001: $write ("type=real ");
2598 4'b0010: $write ("type=cntx ");
2599 4'b0100: $write ("type=page ");
2600 4'b1000: $write ("type=all ");
2601 default:
2602 `PR_ERROR ("tlb_sync", `ERROR,
2603 "Bench Problem - demap_1(%b) should be one-hot.",demap_1);
2604 endcase
2605 end
2606 else begin
2607 $write ("type=autodemap ");
2608 end
2609
2610 $display ("match=%h ts=%0d",
2611 tlb_match,demap_tstamp*`TOP.core_period);
2612
2613 for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // {
2614 if (tlb_match[cnt]==1'b1) begin // {
2615 $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d",
2616 mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period);
2617 end // }
2618 end // }
2619 //--------------------
2620 end // }
2621
2622 //----------------------------------------------------------
2623 // Send I/DHWTW due to HWTW
2624 // Send I/DTLBWRITE due to ASI write
2625
2626 // Save asi num when DTLBREAD happens.
2627 // Otherwise, hold state.
2628 // Send asi num later with DHWTW
2629 for (i=0;i<=7;i=i+1) begin // {
2630 my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i];
2631 end // }
2632
2633 // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en)
2634 // These signals will be interleaved between the threads.
2635 // Need to queue up the signals over time so they can be processed in order.
2636 // Each thread will only be doing 1 thing at a time.
2637
2638 for (i=0;i<=7;i=i+1) begin // {
2639
2640 // tlb_wr[tid] determines if the write is HWTW or TLBWRITE
2641
2642 // data_in[tid] determines which thread will write next
2643 // Use fifo to save the tids of the data_in signals in order
2644
2645 if (data_in[i]) begin // {
2646 if (tlb_wr[i]) begin // {
2647 fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]}
2648 end // }
2649 else begin // {
2650 fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]}
2651
2652 // Signal to nas_pipe to suppress SSTEP as soon we know a tlb write or demap is coming (data_in=1)
2653 // Cannot wait for wr_en because it is possible to miss an SSTEP.
2654 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)",
2655 mycid,i,((mycid * 6'h8) + i[2:0]),tstamp);
2656 `NASTOP.sstep_sent[(mycid * 6'h8) + i[2:0]] <= 1'b1; // suppress SSTEP
2657 end // }
2658 end // }
2659
2660 end // }
2661
2662 //----------------------------------------------------------
2663 // wr_en means that the write is occurring
2664 if (wr_en) begin // {
2665 fifo.pop_fifo ({hwtw,mytid});
2666 mytnum = (mycid * 8) + mytid;
2667
2668 if (hwtw) begin // {
2669 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2670 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DHWTW tid=%d ts=%0d va=%h asi=%h entry=%h",
2671 mycid,mytid,mytnum,tstamp,tte_va,my_asi[mytid],entry);
2672 junk = $sim_send(`PLI_DHWTW, mytnum,tstamp,tte_va,my_asi[mytid],entry);
2673
2674 end //}
2675 end // }
2676 else begin // {
2677 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2678 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h",
2679 mycid,mytid,mytnum,tstamp,entry);
2680 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
2681 mycid,mytid,mytnum,tstamp);
2682 junk = $sim_send(`PLI_DTLBWRITE, mytnum,tstamp,entry);
2683 junk = $sim_send(`PLI_SSTEP, mytnum);
2684
2685 // Check to see if sstep was sent early
2686 if (`NASTOP.sstep_sent[mytnum]==1) begin // {
2687 `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture
2688 end //}
2689
2690 end //}
2691 end // }
2692
2693 //--------------------
2694 if (`PARGS.show_tlb_on) begin // {
2695 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
2696
2697 if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va);
2698 else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va);
2699
2700 case (tte_page_mask)
2701 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d",
2702 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
2703 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d",
2704 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
2705 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d",
2706 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
2707 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d",
2708 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
2709 endcase
2710
2711 if (hwtw) $display (" (hwtw)");
2712 else $display ("");
2713
2714 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
2715
2716 $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d",
2717 tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period);
2718 end // }
2719 //--------------------
2720
2721 end // }
2722
2723end // always}
2724
2725//----------------------------------------------------------
2726`endif
2727endmodule
2728
2729`endif
2730`ifdef CORE_7
2731
2732module dtlb_wr_c7 ();
2733`ifndef GATESIM
2734
2735`include "tlb_sync.vh"
2736`include "nas.vh"
2737parameter NUM_TLB=128;
2738
2739wire [7:0] data_in;
2740wire [7:0] tlb_wr;
2741wire wr_en;
2742wire [7:0] entry;
2743wire [7:0] asi_num;
2744wire asi_enable0; // 1 per thread group
2745wire asi_enable1;
2746wire [7:0] store_asi; // 1 per thread
2747wire [3:0] demap;
2748reg [3:0] demap_1;
2749wire demap_page;
2750wire demap_context;
2751wire demap_real;
2752wire demap_all;
2753wire skip_demap;
2754wire demap_active;
2755wire auto_demap;
2756wire [2:0] demap_tid;
2757reg [2:0] demap_tid_1;
2758reg [5:0] demap_tnum_1;
2759
2760reg [(`TS_WIDTH-1):0] tstamp;
2761reg hwtw;
2762reg [7:0] my_asi [0:7]; // 1 asi number stored per thread
2763reg [(`TS_WIDTH-1):0] demap_tstamp;
2764
2765reg [2:0] mytid;
2766reg [5:0] mytnum;
2767wire [2:0] mycid;
2768integer junk;
2769integer i;
2770reg [7:0] cnt;
2771wire ready;
2772
2773assign mycid = 7;
2774
2775`ifdef DEBUG_TLB
2776 wire [7:0] my_asi0 = my_asi[0];
2777 wire [7:0] my_asi1 = my_asi[1];
2778 wire [7:0] my_asi2 = my_asi[2];
2779 wire [7:0] my_asi3 = my_asi[3];
2780 wire [7:0] my_asi4 = my_asi[4];
2781 wire [7:0] my_asi5 = my_asi[5];
2782 wire [7:0] my_asi6 = my_asi[6];
2783 wire [7:0] my_asi7 = my_asi[7];
2784`endif
2785
2786//----------------------------------------------------------
2787// Instantiate fifo - 1 entry per thread
2788fifo fifo ();
2789// Define fifo parameters
2790defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]}
2791defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection
2792defparam fifo.PTR_BITS = 4;
2793
2794//----------------------------------------------------------
2795// DUT probes
2796
2797assign data_in = `SPC7.mmu.asi.wrote_dtlb;
2798assign tlb_wr = `SPC7.mmu_reload_done;
2799assign wr_en = `SPC7.lsu.tlb.tlb_wr_1_in_dout;
2800
2801assign entry = `SPC7.lsu.tlb.rw_index_1[6:0];
2802
2803assign asi_num = `PROBES7.asi_num;
2804assign asi_enable0 = `PROBES7.tlb_rd_vld_b &
2805 !`PROBES7.tlb_bypass_b &
2806 `SPC7.tlu.fls0.lsu_inst_b;
2807assign asi_enable1 = `PROBES7.tlb_rd_vld_b &
2808 !`PROBES7.tlb_bypass_b &
2809 `SPC7.tlu.fls1.lsu_inst_b;
2810
2811assign store_asi[3:0] = asi_enable0 ? `PROBES7.select_pc_b[3:0] : 4'b0;
2812assign store_asi[7:4] = asi_enable1 ? `PROBES7.select_pc_b[7:4] : 4'b0;
2813
2814assign demap_page = `SPC7.lsu.tlc_demap & ~(demap_context | demap_real | demap_all);
2815assign demap_context = `SPC7.lsu.tlc_demap_context;
2816assign demap_real = `SPC7.lsu.tlc_demap_real;
2817assign demap_all = `SPC7.lsu.tlc_demap_all;
2818assign demap = {demap_all,demap_page,demap_context,demap_real};
2819assign skip_demap =`SPC7.lsu.tlc_wr_u_en;
2820assign demap_tid = `SPC7.lsu.tld.tte1[37:35];
2821
2822// if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS
2823assign demap_active = |demap_1 && !skip_demap;
2824assign auto_demap = |demap_1 && skip_demap;
2825
2826//---------------------
2827// Probes for debugging
2828
2829// defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl
2830
2831// n2_tlb_tl_128x59_cam.sv
2832
2833`define CNTX1_HI 65
2834`define CNTX1_LO 53
2835`define PID_HI 52
2836`define PID_LO 50
2837`define REAL_BIT 49
2838`define VA_47 48
2839`define VA_28 29
2840`define VA_27 28
2841`define VA_22 23
2842`define TTE_VALID 22
2843`define VA_21 21
2844`define VA_16 16
2845`define VA_15 15
2846`define VA_13 13
2847`define CNTX0_HI 12
2848`define CNTX0_LO 0
2849
2850// n2_tlb_tl_128x59_ram.sv
2851
2852`define DATA_PARITY 36
2853`define DATA_PA_39_28_HI 35
2854`define DATA_PA_39_28_LO 24
2855`define DATA_PA_27_22_HI 23
2856`define DATA_PA_27_22_LO 18
2857`define DATA_VA_27_22_V 17
2858`define DATA_PA_21_16_HI 16
2859`define DATA_PA_21_16_LO 11
2860`define DATA_VA_21_16_V 10
2861`define DATA_PA_15_13_HI 9
2862`define DATA_PA_15_13_LO 7
2863`define DATA_VA_15_13_V 6
2864`define DATA_NFO 5
2865`define DATA_IE 4
2866`define DATA_CP 3
2867`define DATA_X 2
2868`define DATA_P 1
2869`define DATA_W 0
2870
2871wire [(NUM_TLB-1):0] tlb_valid;
2872wire [(NUM_TLB-1):0] tlb_match;
2873wire tte_valid;
2874wire [47:0] tte_va;
2875wire [12:0] tte_context;
2876wire tte_real;
2877wire [2:0] tte_pid;
2878wire [2:0] tte_page_mask;
2879wire [39:0] tte_pa;
2880wire tte_nfo;
2881wire tte_ie;
2882wire tte_cp;
2883wire tte_e;
2884wire tte_p;
2885wire tte_w;
2886wire tte_ep;
2887
2888
2889assign tlb_valid = `SPC7.lsu.tlb.array.cam.valid;
2890assign tlb_match = `SPC7.lsu.tlb.array.cam.match;
2891
2892assign tte_va = {`SPC7.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28],
2893 `SPC7.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22],
2894 `SPC7.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16],
2895 `SPC7.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13],
2896 13'b0
2897 };
2898assign tte_context = `SPC7.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO];
2899assign tte_pid = `SPC7.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO];
2900assign tte_real = `SPC7.lsu.tlb.tte_tag_1_dout[`REAL_BIT];
2901assign tte_valid = `SPC7.lsu.tlb.tte_tag_1_dout[`TTE_VALID];
2902
2903assign tte_page_mask = `SPC7.lsu.tlb.tte_page_size_mask_1;
2904
2905assign tte_pa = {`SPC7.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO],
2906 `SPC7.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO],
2907 `SPC7.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO],
2908 `SPC7.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO],
2909 13'b0
2910 };
2911assign tte_nfo = `SPC7.lsu.tlb.tte_data_1[`DATA_NFO];
2912assign tte_ie = `SPC7.lsu.tlb.tte_data_1[`DATA_IE];
2913assign tte_cp = `SPC7.lsu.tlb.tte_data_1[`DATA_CP];
2914assign tte_e = `SPC7.lsu.tlb.tte_data_1[`DATA_X];
2915assign tte_p = `SPC7.lsu.tlb.tte_data_1[`DATA_P];
2916assign tte_w = `SPC7.lsu.tlb.tte_data_1[`DATA_W];
2917assign tte_ep = 1'bx; // Does not apply for DTLB
2918
2919assign ready = `PARGS.tlb_sync_on & !`SPC7.tcu_spc_mbist_start;
2920
2921//----------------------------------------------------------
2922// Initialize state machine to idle state
2923initial begin // {
2924 #1;
2925 hwtw = 1'b0;
2926 for (i=0; i<=7; i=i+1) begin
2927 my_asi[i] = 8'b0;
2928 end
2929 @ (posedge `SPC7.l2clk);
2930
2931end // }
2932
2933//----------------------------------------------------------
2934// Must use negedge to avoid race condition
2935// tlb_entry_replace (aka entry) is created in always block using blocking assignments
2936
2937always @ (negedge (`SPC7.l2clk & ready)) begin // {
2938
2939 tstamp = `TOP.core_cycle_cnt;
2940 demap_tstamp = `TOP.core_cycle_cnt;
2941
2942 // Delay by 1 cycle to align with skip_demap
2943 demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted
2944 demap_tnum_1 <= (mycid * 8) + demap_tid;
2945 demap_1 <= demap;
2946
2947 //----------------------------------------------------------
2948 // Send I/DTLBWRITE due to demap
2949 //
2950
2951 if ((demap!=0) && (demap_1!=0)) begin // {
2952 `PR_ERROR ("tlb_sync", `ERROR,
2953 "C%0d T%0d Illegal Back to Back DTLB demap",
2954 mycid,demap_tid_1);
2955 end // }
2956
2957 if (demap_active) begin // {
2958 fifo.pop_fifo ({hwtw,mytid});
2959 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
2960 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h (demap)",
2961 mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff);
2962 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
2963 mycid,demap_tid_1,demap_tnum_1,demap_tstamp);
2964 junk = $sim_send(`PLI_DTLBWRITE, demap_tnum_1,demap_tstamp,8'hff);
2965 junk = $sim_send(`PLI_SSTEP, demap_tnum_1);
2966
2967 // sstep_sent is asserted when data_in is asserted
2968 // Check to see if sstep was sent early
2969 if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // {
2970 `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture
2971 end //}
2972
2973 end //}
2974 end //}
2975
2976 //--------------------
2977 if (`PARGS.show_tlb_on & (|demap_1)) begin // {
2978 $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1);
2979
2980 if (demap_active) begin
2981 case (demap_1)
2982 4'b0001: $write ("type=real ");
2983 4'b0010: $write ("type=cntx ");
2984 4'b0100: $write ("type=page ");
2985 4'b1000: $write ("type=all ");
2986 default:
2987 `PR_ERROR ("tlb_sync", `ERROR,
2988 "Bench Problem - demap_1(%b) should be one-hot.",demap_1);
2989 endcase
2990 end
2991 else begin
2992 $write ("type=autodemap ");
2993 end
2994
2995 $display ("match=%h ts=%0d",
2996 tlb_match,demap_tstamp*`TOP.core_period);
2997
2998 for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // {
2999 if (tlb_match[cnt]==1'b1) begin // {
3000 $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d",
3001 mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period);
3002 end // }
3003 end // }
3004 //--------------------
3005 end // }
3006
3007 //----------------------------------------------------------
3008 // Send I/DHWTW due to HWTW
3009 // Send I/DTLBWRITE due to ASI write
3010
3011 // Save asi num when DTLBREAD happens.
3012 // Otherwise, hold state.
3013 // Send asi num later with DHWTW
3014 for (i=0;i<=7;i=i+1) begin // {
3015 my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i];
3016 end // }
3017
3018 // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en)
3019 // These signals will be interleaved between the threads.
3020 // Need to queue up the signals over time so they can be processed in order.
3021 // Each thread will only be doing 1 thing at a time.
3022
3023 for (i=0;i<=7;i=i+1) begin // {
3024
3025 // tlb_wr[tid] determines if the write is HWTW or TLBWRITE
3026
3027 // data_in[tid] determines which thread will write next
3028 // Use fifo to save the tids of the data_in signals in order
3029
3030 if (data_in[i]) begin // {
3031 if (tlb_wr[i]) begin // {
3032 fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]}
3033 end // }
3034 else begin // {
3035 fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]}
3036
3037 // Signal to nas_pipe to suppress SSTEP as soon we know a tlb write or demap is coming (data_in=1)
3038 // Cannot wait for wr_en because it is possible to miss an SSTEP.
3039 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)",
3040 mycid,i,((mycid * 6'h8) + i[2:0]),tstamp);
3041 `NASTOP.sstep_sent[(mycid * 6'h8) + i[2:0]] <= 1'b1; // suppress SSTEP
3042 end // }
3043 end // }
3044
3045 end // }
3046
3047 //----------------------------------------------------------
3048 // wr_en means that the write is occurring
3049 if (wr_en) begin // {
3050 fifo.pop_fifo ({hwtw,mytid});
3051 mytnum = (mycid * 8) + mytid;
3052
3053 if (hwtw) begin // {
3054 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
3055 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DHWTW tid=%d ts=%0d va=%h asi=%h entry=%h",
3056 mycid,mytid,mytnum,tstamp,tte_va,my_asi[mytid],entry);
3057 junk = $sim_send(`PLI_DHWTW, mytnum,tstamp,tte_va,my_asi[mytid],entry);
3058
3059 end //}
3060 end // }
3061 else begin // {
3062 if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // {
3063 `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_DTLBWRITE tid=%d ts=%0d entry=%h",
3064 mycid,mytid,mytnum,tstamp,entry);
3065 `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)",
3066 mycid,mytid,mytnum,tstamp);
3067 junk = $sim_send(`PLI_DTLBWRITE, mytnum,tstamp,entry);
3068 junk = $sim_send(`PLI_SSTEP, mytnum);
3069
3070 // Check to see if sstep was sent early
3071 if (`NASTOP.sstep_sent[mytnum]==1) begin // {
3072 `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture
3073 end //}
3074
3075 end //}
3076 end // }
3077
3078 //--------------------
3079 if (`PARGS.show_tlb_on) begin // {
3080 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
3081
3082 if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va);
3083 else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va);
3084
3085 case (tte_page_mask)
3086 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d",
3087 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
3088 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d",
3089 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
3090 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d",
3091 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
3092 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d",
3093 tte_real,tte_context,tte_pid,tstamp*`TOP.core_period);
3094 endcase
3095
3096 if (hwtw) $display (" (hwtw)");
3097 else $display ("");
3098
3099 $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid);
3100
3101 $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d",
3102 tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period);
3103 end // }
3104 //--------------------
3105
3106 end // }
3107
3108end // always}
3109
3110//----------------------------------------------------------
3111`endif
3112endmodule
3113
3114`endif
3115
3116//----------------------------------------------------------
3117//----------------------------------------------------------