Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / vera / classes / systemTapClass.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: systemTapClass.vr
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#include <vera_defines.vrh>
36#include <std_display_class.vrh>
37
38// TAP specific defines
39#include <systemTapDefines.vri>
40
41// jtag interface
42#include <systemTap.if.vri>
43
44#define CLASSNAME BaseSystemTap
45
46extern hdl_task force_tlrState();
47extern hdl_task release_tlrState();
48
49class CLASSNAME {
50 protected bit [3:0] tap_state_reg;
51 protected string dispmonScope;
52 protected StandardDisplay dbg;
53 public tap__port tap_port;
54 protected bit genTlrGlitch;
55
56 task new (
57 StandardDisplay dbgIn
58 );
59 function string BinToChar (
60 bit inbit
61 );
62 function string cnv2str (
63 bit [127:0] data,
64 integer w
65 );
66 function string cnv_instr_2_text (
67 string instr
68 );
69 function string state_id_2_text (
70 bit [3:0] id
71 );
72 function string cnv_domain_2_string (
73 bit [2:0] domain
74 );
75 function bit [3:0] advance_tap_state_reg (
76 bit tms
77 );
78 function bit [15:0] ieeeTap (
79 bit [3:0] current_state
80 );
81 task TapDrive_test_mode (
82 bit test_mode
83 );
84 task TapDrive_trst_n (
85 bit trst_n
86 );
87 task TapDrive_tms (
88 bit tms
89 );
90 task TapDrive_tdi (
91 bit tdi
92 );
93 task TapDriveAdvance_tms (
94 bit tms
95 );
96 task TapResetType1 (
97 );
98 task TapResetType2 (
99 );
100 task check_tck_state (
101 );
102 task TapGoto (
103 bit [3:0] next_state
104 );
105 function bit TapNext (
106 bit [3:0] advance,
107 bit tdi
108 );
109 task TapCaptureData (
110 );
111 function string TapIRLoad (
112 string instr,
113 integer len=8,
114 bit check=1
115 );
116 function bit TapShiftDR_tdi_advance (
117 bit tdi
118 );
119 function string TapDRLoad (
120 string TapIn
121 );
122 function string TapDRGet (
123 integer w
124 );
125 function integer TapWait4DataRdy (
126 integer time_out_limit
127 );
128 function integer TapWait4L2DataRdy (
129 integer time_out_limit
130 );
131 function integer loadUndef (
132 string aUndef
133 );
134 function integer loadBypass (
135 string aBypass
136 );
137 function integer loadIdcode (
138 string aIdcode
139 );
140 function integer loadExtest (
141 string aExtest
142 );
143 function integer checkIdcode (
144 );
145 task Delay (
146 integer count
147 );
148 task toggleDutTck (
149 );
150 task posedge2Dut (
151 );
152 task negedge2Dut (
153 );
154
155 task waitVeraRefTapStateRegChange ( // wait for the variable tap_state_reg changed
156 );
157 function bit [3:0] getVeraRefTapStateReg () { getVeraRefTapStateReg = tap_state_reg; }
158 task enableTlrStateGlitch(
159 );
160 task disableTlrStateGlitch(
161 );
162}
163
164task CLASSNAME::new(StandardDisplay dbgIn) {
165 dispmonScope = "SystemTap";
166 tap_port = tap_bind;
167 dbg = dbgIn;
168 dbg.dispmon(dispmonScope, MON_INFO, "$Id: systemTapClass.vr,v 1.1.1.1 2007/02/13 22:21:19 drp Exp $");
169
170 tap_state_reg = 4'bx;
171 tap_port.$test_mode = 1'b0 soft async; // JTAG debug mode unless told to goto manufacturing test
172 tap_port.$trst_n = 1'bx soft async;
173 tap_port.$tdi = 1'bx soft async;
174 tap_port.$tck2dut = 1'b0 soft async;
175 tap_port.$tms = 1'b1 soft async;
176 dbg.dispmon(dispmonScope, MON_INFO, "WARNING: systemTapClass.vr will not reset the TAP. runRstSequence method of sys_reset.vr class needs to be called to properly reset N2 as per PRM spec");
177 if (!get_plus_arg(CHECK, "noJtagTapReset")) {
178 dbg.dispmon(dispmonScope, MON_INFO, "WARNING: systemTapClass.vr : skip calling TapResetType1() to reset TAP");
179 // Drive TRST_L 0
180 // TRST_L will be de-asserted by sys_reset.vr reset sequence task
181 // TapDrive_trst_n(1'b0);
182 }
183 if (get_plus_arg(CHECK, "disableTlrGlitch")) {
184 dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("Monitoring for glitch-generating transitions on jtag tap_state") );
185 genTlrGlitch = 1'b0;
186 }
187 else {
188 genTlrGlitch = 1'b1;
189 }
190}
191
192function string CLASSNAME::BinToChar(bit inbit) {
193 if(inbit === 1'b1) BinToChar = "1";
194 if(inbit === 1'b0) BinToChar = "0";
195 if(inbit === 1'bx) BinToChar = "x";
196 if(inbit === 1'bz) BinToChar = "z";
197}
198
199//
200//// Should we improve this? This must be slow esp. on long chains -csr
201//// These should use string function...
202function string CLASSNAME::cnv2str(bit [127:0] data, integer w) {
203 integer i;
204 string s = "";
205
206 for ( i=0; i<w; i++ ){
207 if (data[i] == 0)
208 sprintf (s, "%s%s", "0", s);
209 else if (data[i] == 1)
210 sprintf (s, "%s%s", "1", s);
211 else
212 sprintf (s, "%s%s", "x", s);
213 }
214 cnv2str = s;
215}
216
217function string CLASSNAME::cnv_instr_2_text(string instr) {
218 case (instr) {
219
220 // JTAG Public
221 TAP_BYPASS_INST : cnv_instr_2_text = "TAP_BYPASS_INST";
222 TAP_EXTEST_INST : cnv_instr_2_text = "TAP_EXTEST_INST";
223 TAP_IDCODE_INST : cnv_instr_2_text = "TAP_IDCODE_INST";
224 TAP_SAMPLE_INST : cnv_instr_2_text = "TAP_SAMPLE_INST";
225 TAP_HIGHZ_INST : cnv_instr_2_text = "TAP_HIGHZ_INST";
226 TAP_CLAMP_INST : cnv_instr_2_text = "TAP_CLAMP_INST";
227
228 // JTAG Private UCB
229 TAP_CREG_ADDR : cnv_instr_2_text = "TAP_CREG_ADDR";
230 TAP_CREG_WDATA : cnv_instr_2_text = "TAP_CREG_WDATA";
231 TAP_CREG_RDATA : cnv_instr_2_text = "TAP_CREG_RDATA";
232 TAP_CREG_SCRATCH : cnv_instr_2_text = "TAP_CREG_SCRATCH";
233 TAP_NCU_WRITE : cnv_instr_2_text = "TAP_NCU_WRITE";
234 TAP_NCU_READ : cnv_instr_2_text = "TAP_NCU_READ";
235 TAP_NCU_WADDR : cnv_instr_2_text = "TAP_NCU_WADDR";
236 TAP_NCU_WDATA : cnv_instr_2_text = "TAP_NCU_WDATA";
237 TAP_NCU_RADDR : cnv_instr_2_text = "TAP_NCU_RADDR";
238
239 // JTAG Private L2 access
240 TAP_L2_ADDR : cnv_instr_2_text = "TAP_L2_ADDR";
241 TAP_L2_WRDATA : cnv_instr_2_text = "TAP_L2_WRDATA";
242 TAP_L2_WR : cnv_instr_2_text = "TAP_L2_WR";
243 TAP_L2_RD : cnv_instr_2_text = "TAP_L2_RD";
244
245 // JTAG Private MBIST
246 TAP_MBIST_BYPASS : cnv_instr_2_text = "TAP_MBIST_BYPASS";
247 TAP_MBIST_MODE : cnv_instr_2_text = "TAP_MBIST_MODE";
248 TAP_MBIST_START : cnv_instr_2_text = "TAP_MBIST_START";
249 TAP_MBIST_RESULT : cnv_instr_2_text = "TAP_MBIST_RESULT";
250 TAP_MBIST_DIAG : cnv_instr_2_text = "TAP_MBIST_DIAG";
251 TAP_MBIST_GETDONE : cnv_instr_2_text = "TAP_MBIST_GETDONE";
252 TAP_MBIST_GETFAIL : cnv_instr_2_text = "TAP_MBIST_GETFAIL";
253 TAP_MBIST_ABORT : cnv_instr_2_text = "TAP_MBIST_ABORT";
254
255 // JTAG Private Shadow SCAN
256 TAP_SPCTHR0_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR0_SHSCAN";
257 TAP_SPCTHR1_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR1_SHSCAN";
258 TAP_SPCTHR2_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR2_SHSCAN";
259 TAP_SPCTHR3_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR3_SHSCAN";
260 TAP_SPCTHR4_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR4_SHSCAN";
261 TAP_SPCTHR5_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR5_SHSCAN";
262 TAP_SPCTHR6_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR6_SHSCAN";
263 TAP_SPCTHR7_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR7_SHSCAN";
264
265 // JTAG Private Clock Stop
266 TAP_CLOCK_SSTOP : cnv_instr_2_text = "TAP_CLOCK_SSTOP";
267 TAP_CLOCK_HSTOP : cnv_instr_2_text = "TAP_CLOCK_HSTOP";
268 TAP_CLOCK_START : cnv_instr_2_text = "TAP_CLOCK_START";
269 TAP_CLOCK_DOMAIN : cnv_instr_2_text = "TAP_CLOCK_DOMAIN";
270 TAP_CLOCK_STATUS : cnv_instr_2_text = "TAP_CLOCK_STATUS";
271 TAP_CLKSTP_DELAY : cnv_instr_2_text = "TAP_CLKSTP_DELAY";
272 TAP_CORE_SEL : cnv_instr_2_text = "TAP_CORE_SEL";
273 TAP_DE_COUNT : cnv_instr_2_text = "TAP_DE_COUNT";
274 TAP_CYCLE_COUNT : cnv_instr_2_text = "TAP_CYCLE_COUNT";
275 TAP_TCU_DCR : cnv_instr_2_text = "TAP_TCU_DCR";
276 TAP_CORE_RUN_STATUS : cnv_instr_2_text = "TAP_CORE_RUN_STATUS";
277
278 // JTAG Private SCAN
279 TAP_SERSCAN : cnv_instr_2_text = "TAP_SERSCAN";
280 TAP_CHAINSEL : cnv_instr_2_text = "TAP_CHAINSEL";
281 TAP_SCAN_SERIAL : cnv_instr_2_text = "TAP_SCAN_SERIAL";
282 TAP_SCAN_SERIAL_SEL : cnv_instr_2_text = "TAP_SCAN_SERIAL_SEL";
283
284 // JTAG Private EFUSE
285 TAP_FUSE_READ : cnv_instr_2_text = "TAP_FUSE_READ";
286 TAP_FUSE_BYPASS_DATA : cnv_instr_2_text = "TAP_FUSE_BYPASS_DATA";
287 TAP_FUSE_BYPASS : cnv_instr_2_text = "TAP_FUSE_BYPASS";
288 TAP_FUSE_ROW_ADDR : cnv_instr_2_text = "TAP_FUSE_ROW_ADDR";
289 TAP_FUSE_COL_ADDR : cnv_instr_2_text = "TAP_FUSE_COL_ADDR";
290 TAP_FUSE_READ_MODE : cnv_instr_2_text = "TAP_FUSE_READ_MODE";
291 TAP_FUSE_DEST_SAMPLE : cnv_instr_2_text = "TAP_FUSE_DEST_SAMPLE";
292
293 default : cnv_instr_2_text = "*** UNDEFINED ***";
294 }
295}
296
297function string CLASSNAME::state_id_2_text (bit [3:0] id) {
298 case (id) {
299 TAP_RESET : state_id_2_text = "Test-Logic-Reset";
300 TAP_CAPTURE_IR : state_id_2_text = "Capture-IR";
301 TAP_UPDATE_IR : state_id_2_text = "Update-IR";
302 TAP_IDLE : state_id_2_text = "Run-Test-Idle";
303 TAP_PAUSE_IR : state_id_2_text = "Pause-IR";
304 TAP_SHIFT_IR : state_id_2_text = "Shift-IR";
305 TAP_EXIT1_IR : state_id_2_text = "Exit1-IR";
306 TAP_EXIT2_IR : state_id_2_text = "Exit2-IR";
307 TAP_SELECT_DR : state_id_2_text = "Select-DR-Scan";
308 TAP_CAPTURE_DR : state_id_2_text = "Capture-DR";
309 TAP_UPDATE_DR : state_id_2_text = "Update-DR";
310 TAP_SELECT_IR : state_id_2_text = "Select-IR-Scan";
311 TAP_PAUSE_DR : state_id_2_text = "Pause-DR";
312 TAP_SHIFT_DR : state_id_2_text = "Shift-DR";
313 TAP_EXIT1_DR : state_id_2_text = "Exit1-DR";
314 TAP_EXIT2_DR : state_id_2_text = "Exit2-DR";
315 default : state_id_2_text = "*** Unknown ***";
316 }
317}
318
319function string CLASSNAME::cnv_domain_2_string ( bit [2:0] domain ) {
320 if (domain[0]) cnv_domain_2_string = "Application";
321 else if (domain[1:0] == 2'b00) cnv_domain_2_string = "Multi-Step ";
322 else if (domain == 3'b010) cnv_domain_2_string = "PLL Bypass ";
323 else if (domain == 3'b110) cnv_domain_2_string = "Test/TCK ";
324}
325
326//-------- Show where we are going given next TMS ----------
327function bit [3:0] CLASSNAME::advance_tap_state_reg (bit tms) {
328 case (tap_state_reg) {
329 TAP_RESET: advance_tap_state_reg = tms ? TAP_RESET : TAP_IDLE;
330 TAP_CAPTURE_IR: advance_tap_state_reg = tms ? TAP_EXIT1_IR : TAP_SHIFT_IR;
331 TAP_UPDATE_IR:
332 {
333 if (tms) {
334 if (genTlrGlitch) {
335 fork
336 {
337 dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("Glitching tlr tap_state, tap_state: %s", state_id_2_text(tap_state_reg)) );
338 force_tlrState();
339 }
340 join none
341 }
342 advance_tap_state_reg = TAP_SELECT_DR;
343 }
344 else {
345 advance_tap_state_reg = TAP_IDLE;
346 }
347 }
348 TAP_IDLE:
349 {
350 if (tms) {
351 if (genTlrGlitch) {
352 fork
353 {
354 dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("Glitching tlr tap_state, tap_state: %s", state_id_2_text(tap_state_reg)) );
355 force_tlrState();
356 }
357 join none
358 }
359 advance_tap_state_reg = TAP_SELECT_DR;
360 }
361 else {
362 advance_tap_state_reg = TAP_IDLE;
363 }
364 }
365 TAP_PAUSE_IR: advance_tap_state_reg = tms ? TAP_EXIT2_IR : TAP_PAUSE_IR;
366 TAP_SHIFT_IR: advance_tap_state_reg = tms ? TAP_EXIT1_IR : TAP_SHIFT_IR;
367 TAP_EXIT1_IR: advance_tap_state_reg = tms ? TAP_UPDATE_IR : TAP_PAUSE_IR;
368 TAP_EXIT2_IR: advance_tap_state_reg = tms ? TAP_UPDATE_IR : TAP_SHIFT_IR;
369 TAP_SELECT_DR: advance_tap_state_reg = tms ? TAP_SELECT_IR : TAP_CAPTURE_DR;
370 TAP_CAPTURE_DR: advance_tap_state_reg = tms ? TAP_EXIT1_DR : TAP_SHIFT_DR;
371 TAP_UPDATE_DR: advance_tap_state_reg = tms ? TAP_SELECT_DR : TAP_IDLE;
372 TAP_SELECT_IR: advance_tap_state_reg = tms ? TAP_RESET : TAP_CAPTURE_IR;
373 TAP_PAUSE_DR: advance_tap_state_reg = tms ? TAP_EXIT2_DR : TAP_PAUSE_DR;
374 TAP_SHIFT_DR: advance_tap_state_reg = tms ? TAP_EXIT1_DR : TAP_SHIFT_DR;
375 TAP_EXIT1_DR: advance_tap_state_reg = tms ? TAP_UPDATE_DR : TAP_PAUSE_DR;
376 TAP_EXIT2_DR: advance_tap_state_reg = tms ? TAP_UPDATE_DR : TAP_SHIFT_DR;
377 default:
378 dbg.dispmon(dispmonScope, MON_ERR, psprintf("TAP register invalid/out of range: 4'b%4b", tap_state_reg));
379 }
380}
381
382//-------- Walk over the IEEE 1149.1.2001 state machine ----------
383function bit [15:0] CLASSNAME::ieeeTap(bit [3:0] current_state) {
384 case (current_state) {
385 // N2: 111111
386 // N2: 5432109876543210
387 TAP_RESET: ieeeTap = 16'b1000000000000000; // 15
388 TAP_CAPTURE_IR: ieeeTap = 16'b1x11101111111111; // 14
389 TAP_UPDATE_IR: ieeeTap = 16'b11x0111111111111; // 13
390 TAP_IDLE: ieeeTap = 16'b1110111111111111; // 12
391 TAP_PAUSE_IR: ieeeTap = 16'b1111011111111111; // 11
392 TAP_SHIFT_IR: ieeeTap = 16'b1111101111111111; // 10
393 TAP_EXIT1_IR: ieeeTap = 16'b111100x011111111; // 9
394 TAP_EXIT2_IR: ieeeTap = 16'b1111000x11111111; // 8
395 TAP_SELECT_DR: ieeeTap = 16'b11111111x0010000; // 7
396 TAP_CAPTURE_DR: ieeeTap = 16'b111111111x111011; // 6
397 TAP_UPDATE_DR: ieeeTap = 16'b1110111111x11111; // 5
398 TAP_SELECT_IR: ieeeTap = 16'b10010000111x1111; // 4
399 TAP_PAUSE_DR: ieeeTap = 16'b1111111111110111; // 3
400 TAP_SHIFT_DR: ieeeTap = 16'b1111111111111011; // 2
401 TAP_EXIT1_DR: ieeeTap = 16'b11111111111100x0; // 1
402 TAP_EXIT2_DR: ieeeTap = 16'b111111111111000x; // 0
403 }
404}
405
406task CLASSNAME::TapDrive_test_mode(bit test_mode) {
407 dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP test_mode=%0d", test_mode));
408 fork
409 {
410 tap_port.$test_mode = test_mode;
411 }
412 {
413 toggleDutTck();
414 }
415 join
416 terminate;
417}
418
419//-------- The function should not do any @posedge ----------
420task CLASSNAME::TapDrive_trst_n(bit trst_n) {
421 dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP trst_n=%0d", trst_n));
422 // Make TRST_L asyncronous
423 delay(32'hffff & random()); // Pick a random time unit wait
424 fork
425 {
426 tap_port.$trst_n = trst_n async; // Drive the TRST_L
427 }
428 join
429 terminate;
430 tap_state_reg = TAP_RESET;
431}
432
433//-------- The function should not do any @posedge ----------
434task CLASSNAME::TapDrive_tms(bit tms) {
435 dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP tms=%0d", tms));
436 fork
437 {
438 tap_port.$tms = tms;
439 }
440 {
441 tap_port.$tdi = 1'bx;
442 }
443 {
444 toggleDutTck();
445 }
446 join
447 terminate;
448}
449
450task CLASSNAME::TapDriveAdvance_tms(bit tms) {
451 TapDrive_tms(tms);
452 toggleDutTck();
453 tap_state_reg = advance_tap_state_reg(tms);
454}
455
456task CLASSNAME::TapDrive_tdi(bit tdi) {
457 dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP tdi=%0d", tdi));
458 fork
459 {
460 tap_port.$tdi = tdi;
461 }
462 {
463 toggleDutTck();
464 }
465 join
466 terminate;
467}
468
469task CLASSNAME::TapResetType1() {
470 dbg.dispmon(dispmonScope, MON_INFO, "TAP Resetting (default PLL values) ...");
471 TapDrive_trst_n(1'b0);
472 TapDrive_tms(1'b1); // Remain in test-logic-reset after trst_n deassert
473 tap_state_reg = 4'hx;
474 TapDrive_trst_n(1'b1);
475 tap_state_reg = TAP_RESET;
476}
477
478task CLASSNAME::TapResetType2() {
479 // Potential here to randomize -csr
480 // Give ourselves some arbitrary TAP state
481 tap_state_reg = TAP_PAUSE_IR;
482 TapDrive_trst_n(1'b1); // Disable the trst_n pin
483 repeat (5) TapDriveAdvance_tms(1'b1); // IEEE 1149.1.2001; 5 cycle to reset
484}
485
486task CLASSNAME::check_tck_state() {
487 if (tap_port.$tck2dut != 1'b1) {
488 case (tap_state_reg) {
489 TAP_RESET, TAP_IDLE :
490 {
491 dbg.dispmon(dispmonScope, MON_INFO, "Advancing tck");
492 toggleDutTck();
493 }
494 default :
495 dbg.dispmon(dispmonScope, MON_ERR, psprintf("Unable to correct tck state: 4'b%4b", tap_state_reg));
496 }
497 }
498}
499
500task CLASSNAME::TapGoto (bit [3:0] next_state) {
501 bit [15:0] datatemp;
502 bit tms;
503
504 dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP CURRENT: [%s], GOTO: [%s]"
505 , state_id_2_text(tap_state_reg)
506 , state_id_2_text(next_state)));
507 if (tap_state_reg === 4'hx) dbg.dispmon(dispmonScope, MON_ERR, "Unknown TAP state!");
508
509 check_tck_state();
510 while (tap_state_reg != next_state) {
511 datatemp = ieeeTap(tap_state_reg);
512 tms = datatemp[next_state];
513 fork
514 {
515 tap_port.$tms = tms;
516 }
517 {
518 toggleDutTck();
519 }
520 join
521 terminate;
522 tap_state_reg = advance_tap_state_reg(tms);
523 dbg.dispmon(dispmonScope, MON_DEBUG, psprintf("(%0d) %s", tms, state_id_2_text(tap_state_reg)));
524 }
525 case (next_state) {
526 TAP_PAUSE_IR, TAP_PAUSE_DR :
527 {
528 dbg.dispmon(dispmonScope, MON_INFO, psprintf("RANDOM DELAY in TAP state: %s", state_id_2_text(next_state)));
529 Delay(random()%6); // stay in pause state random intervals
530 }
531 TAP_SHIFT_IR, TAP_SHIFT_DR :
532 tap_port.$tdi <= 1'b0 async;
533 }
534}
535
536function bit CLASSNAME::TapNext(bit [3:0] advance, bit tdi) {
537 bit tms;
538 bit tdo_out;
539 check_tck_state();
540
541 if (advance == TAP_NEXT_ADVANCE)
542 case (tap_state_reg) {
543 TAP_SHIFT_DR : tms = 1'b1;
544 TAP_PAUSE_DR : tms = 1'b1;
545 TAP_SHIFT_IR : tms = 1'b1;
546 TAP_PAUSE_IR : tms = 1'b1;
547 default : dbg.dispmon(dispmonScope, MON_ERR, psprintf("Doesn't know where to advance to (%s)", state_id_2_text(tap_state_reg)));
548 }
549 else
550 // remain in current state
551 case (tap_state_reg) {
552 TAP_SHIFT_DR : tms = 1'b0;
553 TAP_PAUSE_DR : tms = 1'b0;
554 TAP_SHIFT_IR : tms = 1'b0;
555 TAP_PAUSE_IR : tms = 1'b0;
556 default :
557 {
558 dbg.dispmon(dispmonScope, MON_ERR, psprintf("Cannot remain in current state (%s)", state_id_2_text(tap_state_reg)));
559 }
560 }
561 fork
562 {
563 tap_port.$tdi = tdi;
564 }
565 {
566 tap_port.$tms = tms;
567 }
568 {
569 tdo_out = tap_port.$tdo;
570 }
571 {
572 toggleDutTck();
573 }
574 join
575 terminate;
576 tap_state_reg = advance_tap_state_reg(tms);
577 TapNext = tdo_out;
578}
579
580task CLASSNAME::TapCaptureData () {
581 dbg.dispmon(dispmonScope, MON_INFO, "TapCaptureData");
582 TapGoto(TAP_EXIT1_DR);
583 TapGoto(TAP_PAUSE_DR);
584 dbg.dispmon(dispmonScope, MON_INFO, "... Done TapCaptureData");
585}
586
587function string CLASSNAME::TapIRLoad(string instr, integer len=8, bit check=1) {
588 integer i;
589 integer remain;
590 string TapOut = "";
591 bit [1:0] lsbMandatory = 2'b01;
592 bit [127:0] b;
593 bit tdo_out;
594
595 if (len != 8) {
596 len = instr.len();
597 }
598 b = instr.atobin();
599 dbg.dispmon(dispmonScope, MON_INFO, psprintf("8'b%8b (%s) ==> IR", b, cnv_instr_2_text(instr)));
600
601 remain = random()%len;
602
603 if (! get_plus_arg(CHECK, "skip_tap_random_pause")) {
604 if (remain) {
605 TapGoto(TAP_PAUSE_IR);
606 }
607 }
608
609 if (tap_state_reg != TAP_SHIFT_IR) TapGoto(TAP_SHIFT_IR);
610 for (i=0; i<len; i++) {
611 tdo_out = TapNext((i == len-1) ? TAP_NEXT_ADVANCE : TAP_NEXT_REMAIN, b[i]);
612 sprintf(TapOut, "%s%s", BinToChar(tdo_out), TapOut);
613 }
614 tap_port.$tdi <= 1'bx;
615 TapGoto(TAP_PAUSE_IR);
616
617 if (check) {
618 // Check that the LSB after the IR capture equals the mandatory 2'b01 -csr
619 b = TapOut.atobin();
620 dbg.dispmon(dispmonScope, MON_INFO, psprintf("IR ==> 'b%0b", b));
621 if (b[1:0] != lsbMandatory) {
622 dbg.dispmon(dispmonScope, MON_ERR, psprintf("LSB of scanned IR ('b%0b) does not match mandatory 2'b01", b));
623 }
624 }
625 TapIRLoad = TapOut;
626}
627
628function bit CLASSNAME::TapShiftDR_tdi_advance(bit tdi) {
629 bit tdo_out;
630
631 dbg.dispmon(dispmonScope, MON_INFO, psprintf("Shifting TDI: %0b", tdi));
632 if (tap_state_reg != TAP_SHIFT_DR) TapGoto(TAP_SHIFT_DR);
633 tdo_out = TapNext(TAP_NEXT_ADVANCE, tdi);
634 TapShiftDR_tdi_advance = tdo_out;
635}
636
637function string CLASSNAME::TapDRLoad(string TapIn) {
638 integer i, len, index, from, to, numDiv, remain;
639 string outbit, tmpStr;
640 string tdo_data = "";
641 bit tdo_out;
642 bit [127:0] b;
643
644 len = TapIn.len();
645 numDiv = len/128;
646 remain = len%128;
647 dbg.dispmon(dispmonScope, MON_INFO, psprintf("'b%0b ==> DR", TapIn));
648
649 if (! get_plus_arg(CHECK, "skip_tap_random_pause")) {
650 if (random()%len) {
651 TapGoto(TAP_PAUSE_DR);
652 }
653 }
654
655 if (tap_state_reg != TAP_SHIFT_DR) TapGoto(TAP_SHIFT_DR);
656 if (numDiv != 0) {
657 for(index=0; index<numDiv; index++) {
658 // TDO - TDI order last bit shifted-in first (TapIn[len])
659 to = len-((index*128)+1);
660 from = to-127;
661 tmpStr = TapIn.substr(from, to);
662 b = tmpStr.atobin();
663 if (tap_state_reg != TAP_SHIFT_DR) TapGoto(TAP_SHIFT_DR);
664 for(i=0; i<128; i++) {
665 tdo_out = TapNext((i == 127) ? TAP_NEXT_ADVANCE : TAP_NEXT_REMAIN, b[i]);
666 sprintf(tdo_data ,"%s%s", BinToChar(tdo_out), tdo_data);
667 }
668 tap_port.$tdi <= 1'bx;
669 TapGoto(TAP_PAUSE_DR);
670 }
671 }
672 if (remain != 0) {
673 if (tap_state_reg != TAP_SHIFT_DR) TapGoto(TAP_SHIFT_DR);
674 // TDO - TDI order last bit shifted-in first (TapIn[len])
675 from = 0;
676 to = remain -1;
677 tmpStr = TapIn.substr(from, to);
678 b = tmpStr.atobin();
679 for(i=0; i<remain; i++) {
680 tdo_out = TapNext((i == remain-1) ? TAP_NEXT_ADVANCE : TAP_NEXT_REMAIN, b[i]);
681 sprintf(tdo_data ,"%s%s", BinToChar(tdo_out), tdo_data);
682 }
683 tap_port.$tdi <= 1'bx;
684 TapGoto(TAP_PAUSE_DR);
685 }
686 dbg.dispmon(dispmonScope, MON_INFO, psprintf("DR ==> 'b%s", tdo_data));
687 TapDRLoad = tdo_data;
688}
689
690function string CLASSNAME::TapDRGet(integer w) {
691 integer i;
692 string get_data = "";
693 bit tdo_out;
694
695 dbg.dispmon(dispmonScope, MON_INFO, psprintf("TapDRGet (w=%0d)", w));
696
697 if (tap_state_reg != TAP_SHIFT_DR) TapGoto(TAP_SHIFT_DR);
698 for (i=0; i<w; i++) {
699 tdo_out = TapNext((i == w-1) ? TAP_NEXT_ADVANCE : TAP_NEXT_REMAIN, 0);
700 sprintf(get_data, "%s%s", BinToChar(tdo_out), get_data);
701 }
702 tap_port.$tdi <= 1'bx;
703 TapGoto(TAP_PAUSE_DR);
704
705 TapDRGet = get_data;
706}
707
708//-------- Wait for an NCU read return --------------
709// System controller gives read error if timeout occurs
710function integer CLASSNAME::TapWait4DataRdy(integer time_out_limit) {
711 integer i;
712 bit tdo_out;
713
714 dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP UCB wait (TCK timeout: %0d cycles)", time_out_limit));
715 fork
716 tdo_out = tap_port.$tdo;
717 toggleDutTck();
718 join
719 terminate;
720 // Wait for the so-called 'sentinel' bit 65; TDO will remain 1'b0 until the read is available
721 // at which time the TDO is set to 1'b1
722 for (i=0; i < time_out_limit && tdo_out !== 1'b1; i++) {
723 fork
724 tdo_out = tap_port.$tdo;
725 toggleDutTck(); // Continue scanning the TDO until it goes high
726 join
727 terminate;
728 }
729 TapWait4DataRdy = (i >= time_out_limit);
730}
731
732//-------- Wait for L2 read return --------------
733// System controller gives read error if timeout occurs
734function integer CLASSNAME::TapWait4L2DataRdy(integer time_out_limit) {
735 integer i;
736 bit tdo_out;
737
738 dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP L2 wait (TCK timeout: %0d cycles)", time_out_limit));
739 fork
740 tdo_out = tap_port.$tdo;
741 toggleDutTck();
742 join
743 terminate;
744 // Wait for the so-called 'sentinel' bit 65; TDO will remain 1'b0 until the read is available
745 // at which time the TDO is set to 1'b1
746 for (i=0; i < time_out_limit && tdo_out !== 1'b1; i++) {
747 fork
748 tdo_out = tap_port.$tdo;
749 toggleDutTck(); // Continue scanning the TDO until it goes high
750 join
751 terminate;
752 TapGoto(TAP_UPDATE_DR);
753 TapGoto(TAP_SHIFT_DR);
754 }
755 TapWait4L2DataRdy = (i >= time_out_limit);
756}
757
758//-------------- JTAG Public ----------------
759function integer CLASSNAME::loadUndef(string aUndef) {
760 // MSB 5432109876543210 LSB
761 string TapIn = "1100001110001100"; // Choose an asymetric pattern
762 string TapOut;
763 bit [127:0] TapInB = TapIn.atobin();
764 bit [127:0] TapOutB;
765 loadUndef = 0;
766
767 TapOut = TapIRLoad(aUndef);
768 TapOut = TapDRLoad(TapIn);
769 TapOutB = TapOut.atobin();
770 if (TapOutB !== { TapInB[14:0], 1'b0 }) { // Bypass should always shift 1'b0 first
771 dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("ERROR: Bypass out ('b%0b) does not match expected", TapOutB) );
772 loadUndef = 1;
773 }
774}
775
776function integer CLASSNAME::loadBypass(string aBypass) {
777 loadBypass = loadUndef(aBypass);
778}
779
780function integer CLASSNAME::loadIdcode(string aIdcode) {
781 void = TapIRLoad(aIdcode);
782 loadIdcode = checkIdcode();
783}
784
785function integer CLASSNAME::loadExtest(string aExtest) {
786 void = TapIRLoad(aExtest);
787 TapGoto(TAP_SHIFT_DR);
788 loadExtest = 0;
789}
790
791function integer CLASSNAME::checkIdcode() {
792 // MSB 5432109876543210 LSB
793 string TapIn = "1100001110001100"; // Choose an asymetric pattern
794 string TapOut;
795 bit [127:0] TapOutB;
796 checkIdcode = 0;
797
798 TapOut = TapDRLoad({TapIn, TapIn});
799 TapOutB = TapOut.atobin();
800 if (TapOutB !== {TAP_VERSION, TAP_PART_NUM, TAP_ID_NUM, 1'b1}) {
801 dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("IDCODE ('b%0b) does not match expected", TapOutB) );
802 checkIdcode = 1;
803 }
804}
805
806task CLASSNAME::Delay(integer count) {
807 repeat(count) toggleDutTck();
808}
809
810task CLASSNAME::toggleDutTck() {
811 posedge2Dut();
812 negedge2Dut();
813}
814
815task CLASSNAME::posedge2Dut() {
816 @(posedge tap_port.$tck);
817 tap_port.$tck2dut = 1'b1 async;
818}
819
820task CLASSNAME::negedge2Dut() {
821 @(negedge tap_port.$tck);
822 tap_port.$tck2dut = 1'b0 async;
823}
824
825//
826// WHAT: wait for tap state reg of the Vera Reference model changed.
827//
828task CLASSNAME::waitVeraRefTapStateRegChange() {
829 wait_var(tap_state_reg);
830}
831
832task CLASSNAME::enableTlrStateGlitch() {
833 this.genTlrGlitch = 1'b1;
834}
835
836task CLASSNAME::disableTlrStateGlitch() {
837 this.genTlrGlitch = 1'b0;
838}
839