// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: systemTapClass.vr
// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// For the avoidance of doubt, and except that if any non-GPL license
// choice is available it will apply instead, Sun elects to use only
// the General Public License version 2 (GPLv2) at this time for any
// software where a choice of GPL license versions is made
// available with the language indicating that GPLv2 or any later version
// may be used, or where a choice of which version of the GPL is applied is
// otherwise unspecified.
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// ========== Copyright Header End ============================================
#include <vera_defines.vrh>
#include <std_display_class.vrh>
#include <systemTapDefines.vri>
#include <systemTap.if.vri>
#define CLASSNAME BaseSystemTap
extern hdl_task force_tlrState();
extern hdl_task release_tlrState();
protected bit [3:0] tap_state_reg;
protected string dispmonScope;
protected StandardDisplay dbg;
public tap__port tap_port;
protected bit genTlrGlitch;
function string BinToChar (
function string cnv2str (
function string cnv_instr_2_text (
function string state_id_2_text (
function string cnv_domain_2_string (
function bit [3:0] advance_tap_state_reg (
function bit [15:0] ieeeTap (
task TapDrive_test_mode (
task TapDriveAdvance_tms (
function string TapIRLoad (
function bit TapShiftDR_tdi_advance (
function string TapDRLoad (
function string TapDRGet (
function integer TapWait4DataRdy (
function integer TapWait4L2DataRdy (
function integer loadUndef (
function integer loadBypass (
function integer loadIdcode (
function integer loadExtest (
function integer checkIdcode (
task waitVeraRefTapStateRegChange ( // wait for the variable tap_state_reg changed
function bit [3:0] getVeraRefTapStateReg () { getVeraRefTapStateReg = tap_state_reg; }
task enableTlrStateGlitch(
task disableTlrStateGlitch(
task CLASSNAME::new(StandardDisplay dbgIn) {
dispmonScope = "SystemTap";
dbg.dispmon(dispmonScope, MON_INFO, "$Id: systemTapClass.vr,v 1.1.1.1 2007/02/13 22:21:19 drp Exp $");
tap_port.$test_mode = 1'b0 soft async; // JTAG debug mode unless told to goto manufacturing test
tap_port.$trst_n = 1'bx soft async;
tap_port.$tdi = 1'bx soft async;
tap_port.$tck2dut = 1'b0 soft async;
tap_port.$tms = 1'b1 soft async;
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");
if (!get_plus_arg(CHECK, "noJtagTapReset")) {
dbg.dispmon(dispmonScope, MON_INFO, "WARNING: systemTapClass.vr : skip calling TapResetType1() to reset TAP");
// TRST_L will be de-asserted by sys_reset.vr reset sequence task
// TapDrive_trst_n(1'b0);
if (get_plus_arg(CHECK, "disableTlrGlitch")) {
dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("Monitoring for glitch-generating transitions on jtag tap_state") );
function string CLASSNAME::BinToChar(bit inbit) {
if(inbit === 1'b1) BinToChar = "1";
if(inbit === 1'b0) BinToChar = "0";
if(inbit === 1'bx) BinToChar = "x";
if(inbit === 1'bz) BinToChar = "z";
//// Should we improve this? This must be slow esp. on long chains -csr
//// These should use string function...
function string CLASSNAME::cnv2str(bit [127:0] data, integer w) {
sprintf (s, "%s%s", "0", s);
sprintf (s, "%s%s", "1", s);
sprintf (s, "%s%s", "x", s);
function string CLASSNAME::cnv_instr_2_text(string instr) {
TAP_BYPASS_INST : cnv_instr_2_text = "TAP_BYPASS_INST";
TAP_EXTEST_INST : cnv_instr_2_text = "TAP_EXTEST_INST";
TAP_IDCODE_INST : cnv_instr_2_text = "TAP_IDCODE_INST";
TAP_SAMPLE_INST : cnv_instr_2_text = "TAP_SAMPLE_INST";
TAP_HIGHZ_INST : cnv_instr_2_text = "TAP_HIGHZ_INST";
TAP_CLAMP_INST : cnv_instr_2_text = "TAP_CLAMP_INST";
TAP_CREG_ADDR : cnv_instr_2_text = "TAP_CREG_ADDR";
TAP_CREG_WDATA : cnv_instr_2_text = "TAP_CREG_WDATA";
TAP_CREG_RDATA : cnv_instr_2_text = "TAP_CREG_RDATA";
TAP_CREG_SCRATCH : cnv_instr_2_text = "TAP_CREG_SCRATCH";
TAP_NCU_WRITE : cnv_instr_2_text = "TAP_NCU_WRITE";
TAP_NCU_READ : cnv_instr_2_text = "TAP_NCU_READ";
TAP_NCU_WADDR : cnv_instr_2_text = "TAP_NCU_WADDR";
TAP_NCU_WDATA : cnv_instr_2_text = "TAP_NCU_WDATA";
TAP_NCU_RADDR : cnv_instr_2_text = "TAP_NCU_RADDR";
// JTAG Private L2 access
TAP_L2_ADDR : cnv_instr_2_text = "TAP_L2_ADDR";
TAP_L2_WRDATA : cnv_instr_2_text = "TAP_L2_WRDATA";
TAP_L2_WR : cnv_instr_2_text = "TAP_L2_WR";
TAP_L2_RD : cnv_instr_2_text = "TAP_L2_RD";
TAP_MBIST_BYPASS : cnv_instr_2_text = "TAP_MBIST_BYPASS";
TAP_MBIST_MODE : cnv_instr_2_text = "TAP_MBIST_MODE";
TAP_MBIST_START : cnv_instr_2_text = "TAP_MBIST_START";
TAP_MBIST_RESULT : cnv_instr_2_text = "TAP_MBIST_RESULT";
TAP_MBIST_DIAG : cnv_instr_2_text = "TAP_MBIST_DIAG";
TAP_MBIST_GETDONE : cnv_instr_2_text = "TAP_MBIST_GETDONE";
TAP_MBIST_GETFAIL : cnv_instr_2_text = "TAP_MBIST_GETFAIL";
TAP_MBIST_ABORT : cnv_instr_2_text = "TAP_MBIST_ABORT";
// JTAG Private Shadow SCAN
TAP_SPCTHR0_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR0_SHSCAN";
TAP_SPCTHR1_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR1_SHSCAN";
TAP_SPCTHR2_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR2_SHSCAN";
TAP_SPCTHR3_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR3_SHSCAN";
TAP_SPCTHR4_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR4_SHSCAN";
TAP_SPCTHR5_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR5_SHSCAN";
TAP_SPCTHR6_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR6_SHSCAN";
TAP_SPCTHR7_SHSCAN : cnv_instr_2_text = "TAP_SPCTHR7_SHSCAN";
// JTAG Private Clock Stop
TAP_CLOCK_SSTOP : cnv_instr_2_text = "TAP_CLOCK_SSTOP";
TAP_CLOCK_HSTOP : cnv_instr_2_text = "TAP_CLOCK_HSTOP";
TAP_CLOCK_START : cnv_instr_2_text = "TAP_CLOCK_START";
TAP_CLOCK_DOMAIN : cnv_instr_2_text = "TAP_CLOCK_DOMAIN";
TAP_CLOCK_STATUS : cnv_instr_2_text = "TAP_CLOCK_STATUS";
TAP_CLKSTP_DELAY : cnv_instr_2_text = "TAP_CLKSTP_DELAY";
TAP_CORE_SEL : cnv_instr_2_text = "TAP_CORE_SEL";
TAP_DE_COUNT : cnv_instr_2_text = "TAP_DE_COUNT";
TAP_CYCLE_COUNT : cnv_instr_2_text = "TAP_CYCLE_COUNT";
TAP_TCU_DCR : cnv_instr_2_text = "TAP_TCU_DCR";
TAP_CORE_RUN_STATUS : cnv_instr_2_text = "TAP_CORE_RUN_STATUS";
TAP_SERSCAN : cnv_instr_2_text = "TAP_SERSCAN";
TAP_CHAINSEL : cnv_instr_2_text = "TAP_CHAINSEL";
TAP_SCAN_SERIAL : cnv_instr_2_text = "TAP_SCAN_SERIAL";
TAP_SCAN_SERIAL_SEL : cnv_instr_2_text = "TAP_SCAN_SERIAL_SEL";
TAP_FUSE_READ : cnv_instr_2_text = "TAP_FUSE_READ";
TAP_FUSE_BYPASS_DATA : cnv_instr_2_text = "TAP_FUSE_BYPASS_DATA";
TAP_FUSE_BYPASS : cnv_instr_2_text = "TAP_FUSE_BYPASS";
TAP_FUSE_ROW_ADDR : cnv_instr_2_text = "TAP_FUSE_ROW_ADDR";
TAP_FUSE_COL_ADDR : cnv_instr_2_text = "TAP_FUSE_COL_ADDR";
TAP_FUSE_READ_MODE : cnv_instr_2_text = "TAP_FUSE_READ_MODE";
TAP_FUSE_DEST_SAMPLE : cnv_instr_2_text = "TAP_FUSE_DEST_SAMPLE";
default : cnv_instr_2_text = "*** UNDEFINED ***";
function string CLASSNAME::state_id_2_text (bit [3:0] id) {
TAP_RESET : state_id_2_text = "Test-Logic-Reset";
TAP_CAPTURE_IR : state_id_2_text = "Capture-IR";
TAP_UPDATE_IR : state_id_2_text = "Update-IR";
TAP_IDLE : state_id_2_text = "Run-Test-Idle";
TAP_PAUSE_IR : state_id_2_text = "Pause-IR";
TAP_SHIFT_IR : state_id_2_text = "Shift-IR";
TAP_EXIT1_IR : state_id_2_text = "Exit1-IR";
TAP_EXIT2_IR : state_id_2_text = "Exit2-IR";
TAP_SELECT_DR : state_id_2_text = "Select-DR-Scan";
TAP_CAPTURE_DR : state_id_2_text = "Capture-DR";
TAP_UPDATE_DR : state_id_2_text = "Update-DR";
TAP_SELECT_IR : state_id_2_text = "Select-IR-Scan";
TAP_PAUSE_DR : state_id_2_text = "Pause-DR";
TAP_SHIFT_DR : state_id_2_text = "Shift-DR";
TAP_EXIT1_DR : state_id_2_text = "Exit1-DR";
TAP_EXIT2_DR : state_id_2_text = "Exit2-DR";
default : state_id_2_text = "*** Unknown ***";
function string CLASSNAME::cnv_domain_2_string ( bit [2:0] domain ) {
if (domain[0]) cnv_domain_2_string = "Application";
else if (domain[1:0] == 2'b00) cnv_domain_2_string = "Multi-Step ";
else if (domain == 3'b010) cnv_domain_2_string = "PLL Bypass ";
else if (domain == 3'b110) cnv_domain_2_string = "Test/TCK ";
//-------- Show where we are going given next TMS ----------
function bit [3:0] CLASSNAME::advance_tap_state_reg (bit tms) {
TAP_RESET: advance_tap_state_reg = tms ? TAP_RESET : TAP_IDLE;
TAP_CAPTURE_IR: advance_tap_state_reg = tms ? TAP_EXIT1_IR : TAP_SHIFT_IR;
dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("Glitching tlr tap_state, tap_state: %s", state_id_2_text(tap_state_reg)) );
advance_tap_state_reg = TAP_SELECT_DR;
advance_tap_state_reg = TAP_IDLE;
dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("Glitching tlr tap_state, tap_state: %s", state_id_2_text(tap_state_reg)) );
advance_tap_state_reg = TAP_SELECT_DR;
advance_tap_state_reg = TAP_IDLE;
TAP_PAUSE_IR: advance_tap_state_reg = tms ? TAP_EXIT2_IR : TAP_PAUSE_IR;
TAP_SHIFT_IR: advance_tap_state_reg = tms ? TAP_EXIT1_IR : TAP_SHIFT_IR;
TAP_EXIT1_IR: advance_tap_state_reg = tms ? TAP_UPDATE_IR : TAP_PAUSE_IR;
TAP_EXIT2_IR: advance_tap_state_reg = tms ? TAP_UPDATE_IR : TAP_SHIFT_IR;
TAP_SELECT_DR: advance_tap_state_reg = tms ? TAP_SELECT_IR : TAP_CAPTURE_DR;
TAP_CAPTURE_DR: advance_tap_state_reg = tms ? TAP_EXIT1_DR : TAP_SHIFT_DR;
TAP_UPDATE_DR: advance_tap_state_reg = tms ? TAP_SELECT_DR : TAP_IDLE;
TAP_SELECT_IR: advance_tap_state_reg = tms ? TAP_RESET : TAP_CAPTURE_IR;
TAP_PAUSE_DR: advance_tap_state_reg = tms ? TAP_EXIT2_DR : TAP_PAUSE_DR;
TAP_SHIFT_DR: advance_tap_state_reg = tms ? TAP_EXIT1_DR : TAP_SHIFT_DR;
TAP_EXIT1_DR: advance_tap_state_reg = tms ? TAP_UPDATE_DR : TAP_PAUSE_DR;
TAP_EXIT2_DR: advance_tap_state_reg = tms ? TAP_UPDATE_DR : TAP_SHIFT_DR;
dbg.dispmon(dispmonScope, MON_ERR, psprintf("TAP register invalid/out of range: 4'b%4b", tap_state_reg));
//-------- Walk over the IEEE 1149.1.2001 state machine ----------
function bit [15:0] CLASSNAME::ieeeTap(bit [3:0] current_state) {
TAP_RESET: ieeeTap = 16'b1000000000000000; // 15
TAP_CAPTURE_IR: ieeeTap = 16'b1x11101111111111; // 14
TAP_UPDATE_IR: ieeeTap = 16'b11x0111111111111; // 13
TAP_IDLE: ieeeTap = 16'b1110111111111111; // 12
TAP_PAUSE_IR: ieeeTap = 16'b1111011111111111; // 11
TAP_SHIFT_IR: ieeeTap = 16'b1111101111111111; // 10
TAP_EXIT1_IR: ieeeTap = 16'b111100x011111111; // 9
TAP_EXIT2_IR: ieeeTap = 16'b1111000x11111111; // 8
TAP_SELECT_DR: ieeeTap = 16'b11111111x0010000; // 7
TAP_CAPTURE_DR: ieeeTap = 16'b111111111x111011; // 6
TAP_UPDATE_DR: ieeeTap = 16'b1110111111x11111; // 5
TAP_SELECT_IR: ieeeTap = 16'b10010000111x1111; // 4
TAP_PAUSE_DR: ieeeTap = 16'b1111111111110111; // 3
TAP_SHIFT_DR: ieeeTap = 16'b1111111111111011; // 2
TAP_EXIT1_DR: ieeeTap = 16'b11111111111100x0; // 1
TAP_EXIT2_DR: ieeeTap = 16'b111111111111000x; // 0
task CLASSNAME::TapDrive_test_mode(bit test_mode) {
dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP test_mode=%0d", test_mode));
tap_port.$test_mode = test_mode;
//-------- The function should not do any @posedge ----------
task CLASSNAME::TapDrive_trst_n(bit trst_n) {
dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP trst_n=%0d", trst_n));
// Make TRST_L asyncronous
delay(32'hffff & random()); // Pick a random time unit wait
tap_port.$trst_n = trst_n async; // Drive the TRST_L
tap_state_reg = TAP_RESET;
//-------- The function should not do any @posedge ----------
task CLASSNAME::TapDrive_tms(bit tms) {
dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP tms=%0d", tms));
task CLASSNAME::TapDriveAdvance_tms(bit tms) {
tap_state_reg = advance_tap_state_reg(tms);
task CLASSNAME::TapDrive_tdi(bit tdi) {
dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP tdi=%0d", tdi));
task CLASSNAME::TapResetType1() {
dbg.dispmon(dispmonScope, MON_INFO, "TAP Resetting (default PLL values) ...");
TapDrive_tms(1'b1); // Remain in test-logic-reset after trst_n deassert
tap_state_reg = TAP_RESET;
task CLASSNAME::TapResetType2() {
// Potential here to randomize -csr
// Give ourselves some arbitrary TAP state
tap_state_reg = TAP_PAUSE_IR;
TapDrive_trst_n(1'b1); // Disable the trst_n pin
repeat (5) TapDriveAdvance_tms(1'b1); // IEEE 1149.1.2001; 5 cycle to reset
task CLASSNAME::check_tck_state() {
if (tap_port.$tck2dut != 1'b1) {
dbg.dispmon(dispmonScope, MON_INFO, "Advancing tck");
dbg.dispmon(dispmonScope, MON_ERR, psprintf("Unable to correct tck state: 4'b%4b", tap_state_reg));
task CLASSNAME::TapGoto (bit [3:0] next_state) {
dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP CURRENT: [%s], GOTO: [%s]"
, state_id_2_text(tap_state_reg)
, state_id_2_text(next_state)));
if (tap_state_reg === 4'hx) dbg.dispmon(dispmonScope, MON_ERR, "Unknown TAP state!");
while (tap_state_reg != next_state) {
datatemp = ieeeTap(tap_state_reg);
tms = datatemp[next_state];
tap_state_reg = advance_tap_state_reg(tms);
dbg.dispmon(dispmonScope, MON_DEBUG, psprintf("(%0d) %s", tms, state_id_2_text(tap_state_reg)));
TAP_PAUSE_IR, TAP_PAUSE_DR :
dbg.dispmon(dispmonScope, MON_INFO, psprintf("RANDOM DELAY in TAP state: %s", state_id_2_text(next_state)));
Delay(random()%6); // stay in pause state random intervals
TAP_SHIFT_IR, TAP_SHIFT_DR :
tap_port.$tdi <= 1'b0 async;
function bit CLASSNAME::TapNext(bit [3:0] advance, bit tdi) {
if (advance == TAP_NEXT_ADVANCE)
TAP_SHIFT_DR : tms = 1'b1;
TAP_PAUSE_DR : tms = 1'b1;
TAP_SHIFT_IR : tms = 1'b1;
TAP_PAUSE_IR : tms = 1'b1;
default : dbg.dispmon(dispmonScope, MON_ERR, psprintf("Doesn't know where to advance to (%s)", state_id_2_text(tap_state_reg)));
// remain in current state
TAP_SHIFT_DR : tms = 1'b0;
TAP_PAUSE_DR : tms = 1'b0;
TAP_SHIFT_IR : tms = 1'b0;
TAP_PAUSE_IR : tms = 1'b0;
dbg.dispmon(dispmonScope, MON_ERR, psprintf("Cannot remain in current state (%s)", state_id_2_text(tap_state_reg)));
tap_state_reg = advance_tap_state_reg(tms);
task CLASSNAME::TapCaptureData () {
dbg.dispmon(dispmonScope, MON_INFO, "TapCaptureData");
dbg.dispmon(dispmonScope, MON_INFO, "... Done TapCaptureData");
function string CLASSNAME::TapIRLoad(string instr, integer len=8, bit check=1) {
bit [1:0] lsbMandatory = 2'b01;
dbg.dispmon(dispmonScope, MON_INFO, psprintf("8'b%8b (%s) ==> IR", b, cnv_instr_2_text(instr)));
if (! get_plus_arg(CHECK, "skip_tap_random_pause")) {
if (tap_state_reg != TAP_SHIFT_IR) TapGoto(TAP_SHIFT_IR);
tdo_out = TapNext((i == len-1) ? TAP_NEXT_ADVANCE : TAP_NEXT_REMAIN, b[i]);
sprintf(TapOut, "%s%s", BinToChar(tdo_out), TapOut);
// Check that the LSB after the IR capture equals the mandatory 2'b01 -csr
dbg.dispmon(dispmonScope, MON_INFO, psprintf("IR ==> 'b%0b", b));
if (b[1:0] != lsbMandatory) {
dbg.dispmon(dispmonScope, MON_ERR, psprintf("LSB of scanned IR ('b%0b) does not match mandatory 2'b01", b));
function bit CLASSNAME::TapShiftDR_tdi_advance(bit tdi) {
dbg.dispmon(dispmonScope, MON_INFO, psprintf("Shifting TDI: %0b", tdi));
if (tap_state_reg != TAP_SHIFT_DR) TapGoto(TAP_SHIFT_DR);
tdo_out = TapNext(TAP_NEXT_ADVANCE, tdi);
TapShiftDR_tdi_advance = tdo_out;
function string CLASSNAME::TapDRLoad(string TapIn) {
integer i, len, index, from, to, numDiv, remain;
dbg.dispmon(dispmonScope, MON_INFO, psprintf("'b%0b ==> DR", TapIn));
if (! get_plus_arg(CHECK, "skip_tap_random_pause")) {
if (tap_state_reg != TAP_SHIFT_DR) TapGoto(TAP_SHIFT_DR);
for(index=0; index<numDiv; index++) {
// TDO - TDI order last bit shifted-in first (TapIn[len])
to = len-((index*128)+1);
tmpStr = TapIn.substr(from, to);
if (tap_state_reg != TAP_SHIFT_DR) TapGoto(TAP_SHIFT_DR);
tdo_out = TapNext((i == 127) ? TAP_NEXT_ADVANCE : TAP_NEXT_REMAIN, b[i]);
sprintf(tdo_data ,"%s%s", BinToChar(tdo_out), tdo_data);
if (tap_state_reg != TAP_SHIFT_DR) TapGoto(TAP_SHIFT_DR);
// TDO - TDI order last bit shifted-in first (TapIn[len])
tmpStr = TapIn.substr(from, to);
for(i=0; i<remain; i++) {
tdo_out = TapNext((i == remain-1) ? TAP_NEXT_ADVANCE : TAP_NEXT_REMAIN, b[i]);
sprintf(tdo_data ,"%s%s", BinToChar(tdo_out), tdo_data);
dbg.dispmon(dispmonScope, MON_INFO, psprintf("DR ==> 'b%s", tdo_data));
function string CLASSNAME::TapDRGet(integer w) {
dbg.dispmon(dispmonScope, MON_INFO, psprintf("TapDRGet (w=%0d)", w));
if (tap_state_reg != TAP_SHIFT_DR) TapGoto(TAP_SHIFT_DR);
tdo_out = TapNext((i == w-1) ? TAP_NEXT_ADVANCE : TAP_NEXT_REMAIN, 0);
sprintf(get_data, "%s%s", BinToChar(tdo_out), get_data);
//-------- Wait for an NCU read return --------------
// System controller gives read error if timeout occurs
function integer CLASSNAME::TapWait4DataRdy(integer time_out_limit) {
dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP UCB wait (TCK timeout: %0d cycles)", time_out_limit));
// Wait for the so-called 'sentinel' bit 65; TDO will remain 1'b0 until the read is available
// at which time the TDO is set to 1'b1
for (i=0; i < time_out_limit && tdo_out !== 1'b1; i++) {
toggleDutTck(); // Continue scanning the TDO until it goes high
TapWait4DataRdy = (i >= time_out_limit);
//-------- Wait for L2 read return --------------
// System controller gives read error if timeout occurs
function integer CLASSNAME::TapWait4L2DataRdy(integer time_out_limit) {
dbg.dispmon(dispmonScope, MON_INFO, psprintf("TAP L2 wait (TCK timeout: %0d cycles)", time_out_limit));
// Wait for the so-called 'sentinel' bit 65; TDO will remain 1'b0 until the read is available
// at which time the TDO is set to 1'b1
for (i=0; i < time_out_limit && tdo_out !== 1'b1; i++) {
toggleDutTck(); // Continue scanning the TDO until it goes high
TapWait4L2DataRdy = (i >= time_out_limit);
//-------------- JTAG Public ----------------
function integer CLASSNAME::loadUndef(string aUndef) {
// MSB 5432109876543210 LSB
string TapIn = "1100001110001100"; // Choose an asymetric pattern
bit [127:0] TapInB = TapIn.atobin();
TapOut = TapIRLoad(aUndef);
TapOut = TapDRLoad(TapIn);
TapOutB = TapOut.atobin();
if (TapOutB !== { TapInB[14:0], 1'b0 }) { // Bypass should always shift 1'b0 first
dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("ERROR: Bypass out ('b%0b) does not match expected", TapOutB) );
function integer CLASSNAME::loadBypass(string aBypass) {
loadBypass = loadUndef(aBypass);
function integer CLASSNAME::loadIdcode(string aIdcode) {
void = TapIRLoad(aIdcode);
loadIdcode = checkIdcode();
function integer CLASSNAME::loadExtest(string aExtest) {
void = TapIRLoad(aExtest);
function integer CLASSNAME::checkIdcode() {
// MSB 5432109876543210 LSB
string TapIn = "1100001110001100"; // Choose an asymetric pattern
TapOut = TapDRLoad({TapIn, TapIn});
TapOutB = TapOut.atobin();
if (TapOutB !== {TAP_VERSION, TAP_PART_NUM, TAP_ID_NUM, 1'b1}) {
dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("IDCODE ('b%0b) does not match expected", TapOutB) );
task CLASSNAME::Delay(integer count) {
repeat(count) toggleDutTck();
task CLASSNAME::toggleDutTck() {
task CLASSNAME::posedge2Dut() {
@(posedge tap_port.$tck);
tap_port.$tck2dut = 1'b1 async;
task CLASSNAME::negedge2Dut() {
@(negedge tap_port.$tck);
tap_port.$tck2dut = 1'b0 async;
// WHAT: wait for tap state reg of the Vera Reference model changed.
task CLASSNAME::waitVeraRefTapStateRegChange() {
task CLASSNAME::enableTlrStateGlitch() {
this.genTlrGlitch = 1'b1;
task CLASSNAME::disableTlrStateGlitch() {
this.genTlrGlitch = 1'b0;