// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: asmEventsToVera.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>
#define STD_DISP this.dbg
#include <plusArgMacros.vri>
#include <std_display_class.vrh>
#include <asmEventsToVera.if.vrh>
#include <baseAsmToVeraIntf.vrh>
// class and header *MUST* be created in each bench that uses User Events.
// Make sure Vera compiles with the right asmToVeraIntf file for your
// bench. (Use -I paths!)
#include <asmToVeraIntf.vrh>
//#define DEBUGASMEVENTSTOVERA
local string className = "AsmEventsToVera";
local AsmToVeraIntf asmToVeraIntf; // each bench creates & compiles this class!!
local asmEventCore probes[64];
local reg [63:0] enabledTids;
local reg [63:0] outOfBoot = 0;
local reg [63:0] startBoot = 0;
local reg [63:0] inBoot = 0;
local StandardDisplay dbg;
//// local reg debug = 0;
local EventClass userEventsList []; // pc's that have user event(s)
local integer eventCount = 0;
// never retire an event (asm runs again after reset)
local reg eventsNeverDone;
task new(StandardDisplay dbg,
task readEventFile(string file,
local task extract(string str, var string items [ITEMCOUNT]);
local task parseTrig(string items [ITEMCOUNT]);
local task mainMonitor();
local task serviceEvent(reg [63:0] pc, reg [5:0] fromTid);
/////////////////////////////////////////////////////////////////////////
// process $EV user event line from .s file, create and store user event.
// None of this will make sense until you read:
// Add to the case below to add a new User Event
/////////////////////////////////////////////////////////////////////////
task AsmEventsToVera::parseTrig(string items [ITEMCOUNT])
// NOTE: The "1," in trig_pc_d(1, @VA... has no know use today. N1 called
// this paramater "kind" and it had values of 0, 1, 2, and 3 in
// diags. The first pass vera code looked for values of 1 and
// 2. The second pass code, done in C, does not use this paramater
// at all. In the first pass vera code, a value of 2 meant that an
// intp task should send an interrupt to the given thread at each
// of 8 cores. A value of 1 for kind meant that the target core
// should be what was specified in the $EV, else the target core
// will be core 0 (or all cores if kind is 2). N2 ignores this
// reg [63:0] firstParam = 0; // The "1," in trig_pc_d(1, @VA... has no know use today.
if (items[i] !== "trig_pc_d") error("first item not trig_pc_d\n");
// firstParam = str.atohex();
"generic_ev" : { // generic user event for general use (6/06)
evnt.routine = items[i]; i++;
evnt.miscStrA = str; // arg1 is a string
if (str.match("0x")) str = str.postmatch();
evnt.misc64A = str.atohex(); // arg2 is a 64-bit value
if (str.match("0x")) str = str.postmatch();
evnt.misc64B = str.atohex(); // arg3 is a 64-bit value
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
"intp": { // ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) -> intp(1, 1, 1)
evnt.routine = items[i]; i++;
evnt.tid = str.atohex(); // 64 tids // target tid
evnt.intType = str.atohex(); // type
evnt.misc64A = str.atohex(); // vec
if (str == "*") evnt.src = 64;
else evnt.src = str.atohex(); // srcTid
if (str == "*") evnt.wait = 0;
else evnt.wait = str.atoi(); // wait
if (str == "*") evnt.thisTid = 64;
else evnt.thisTid = str.atohex(); // thisTid
if (str == "*") evnt.tidMask = 0;
else evnt.tidMask = str.atohex(); // targetTidMask
if (str !== "*") evnt.multiShot = str.atohex(); // multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
if (str == "*") evnt.wait = 0;
else evnt.wait = str.atoi();
if (str == "*") evnt.miscIntA = 0;
else evnt.miscIntA = str.atoi();
//making this permanently multishot
evnt.multiShot = 1; // multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
if (str == "*") evnt.wait = 0;
else evnt.wait = str.atoi();
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
// Does not use CPX stall input! Starves SPC of response pkts.
evnt.routine = items[i]; i++;
evnt.tid = str.atohex(); // 64 tids
evnt.miscIntA = str.atoi(); // duration
if (str == "*") evnt.wait = 0;
else evnt.wait = str.atoi();
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
} else error("cpx_stall: thread ID too high: 0x%0h\n",evnt.tid);
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) -> printf("your text", thisTid, multiShot)
evnt.routine = items[i]; i++;
evnt.miscStrA = items[i]; i++;
if (str !== "*") evnt.thisTid = str.atohex(); // thisTid
if (str !== "*") evnt.multiShot = str.atohex(); // multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
evnt.misc64A = str.atohex(); // addr
evnt.misc64B = str.atohex(); // amount
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
// SPC BFM will do a store to L2. Pick correct port w/ BFM!!!
evnt.routine = items[i]; i++;
evnt.tid = str.atohex(); // 8 cores
evnt.misc64A = str.atohex(); // addr
evnt.misc64B = str.atohex(); // data
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
} else error("store: CPU ID too high: 0x%0h\n",evnt.tid);
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
// ************* Trap Counting Task **************
evnt.routine = items[i]; i++;
evnt.misc64A = str.atohex(); // injectErr
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
// ************* Data Array Injection **************
evnt.routine = items[i]; i++;
evnt.misc64A = str.atohex(); // injectErr
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
// ************* Tag Array Injection **************
evnt.routine = items[i]; i++;
evnt.misc64A = str.atohex(); // injectErr
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
// ************* IOS Err Injection **************
evnt.routine = items[i]; i++;
evnt.miscStrA = str; // Error type
evnt.misc64A = str.atohex(); // Tag
evnt.misc64B = str.atohex(); // PA
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
evnt.routine = items[i]; i++;
evnt.miscStrA = str; // Error type
evnt.misc64A = str.atohex(); //
evnt.misc64B = str.atohex(); //
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
evnt.routine = items[i]; i++;
evnt.misc64A = str.atohex(); // addr
evnt.misc64B = str.atohex(); // amount
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
evnt.routine = items[i]; i++;
evnt.misc64A = str.atohex(); // addr
evnt.misc64B = str.atohex(); // amount
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
evnt.routine = items[i]; i++;
if (str.match("0x")) str = str.postmatch();
evnt.misc64A = str.atohex(); // addr
if (str.match("0x")) str = str.postmatch();
evnt.misc64B = str.atohex(); // data
if (str.match("0x")) str = str.postmatch();
evnt.misc64C = str.atohex(); // jtagDoneAddrMem
evnt.misc01A = str.atobin(); // rdWr rd=0, wr=1
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
evnt.routine = items[i]; i++;
evnt.tid = str.atohex(); // mac_port
if (str.match("0x")) str = str.postmatch();
evnt.misc64A = str.atohex(); // frame_type
if (str.match("0x")) str = str.postmatch();
evnt.misc64B = str.atohex(); // frame_class
if (str.match("0x")) str = str.postmatch();
evnt.misc64C = str.atohex(); // data_length
evnt.misc01A = str.atohex(); // tx_multi_port
if (str.match("0x")) str = str.postmatch();
evnt.misc64D = str.atohex(); // data_length_p1
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
evnt.tid = str.atohex(); // mac_port
evnt.misc64B = str.atohex(); // dma_no
// if (str == "*") evnt.miscIntA = 0;
// else evnt.miscIntA = str.atoi(); dma_no
evnt.misc01A = str.atohex(); // tx_multi_port
if (str.match("0x")) str = str.postmatch();
evnt.misc64C = str.atohex(); // tx_multi_dma_p0
if (str.match("0x")) str = str.postmatch();
evnt.misc64D = str.atohex(); // tx_multi_dma_p1
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
evnt.tid = str.atohex(); // mac_port
evnt.misc64B = str.atohex(); // dma_no
evnt.misc01A = str.atohex(); // tx_multi_port
if (str.match("0x")) str = str.postmatch();
evnt.misc64C = str.atohex(); // tx_multi_dma_p0
if (str.match("0x")) str = str.postmatch();
evnt.misc64D = str.atohex(); // tx_multi_dma_p1
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
evnt.misc01B = str.atohex(); // mac_port
evnt.misc64B = str.atohex(); // dma_no
evnt.misc64A = str.atohex(); // SetTxMaxBurst_Data
evnt.misc01A = str.atohex(); // tx_multi_port
if (str.match("0x")) str = str.postmatch();
evnt.misc64C = str.atohex(); // tx_multi_dma_p0
if (str.match("0x")) str = str.postmatch();
evnt.misc64D = str.atohex(); // tx_multi_dma_p1
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
evnt.misc01B = str.atohex(); // mac_port
evnt.misc64B = str.atohex(); // dma_no
// evnt.tid = str.atohex(); dma_no
evnt.misc64A = str.atohex(); // Xlate
evnt.misc01A = str.atohex(); // tx_multi_port
if (str.match("0x")) str = str.postmatch();
evnt.misc64C = str.atohex(); // tx_multi_dma_p0
if (str.match("0x")) str = str.postmatch();
evnt.misc64D = str.atohex(); // tx_multi_dma_p1
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
evnt.misc64B = str.atohex(); // mac_port
evnt.tid = str.atohex(); // dma_activelist
evnt.misc01A = str.atohex(); // tx_multi_port
if (str.match("0x")) str = str.postmatch();
evnt.misc64C = str.atohex(); // tx_multi_dma_p0
if (str.match("0x")) str = str.postmatch();
evnt.misc64D = str.atohex(); // tx_multi_dma_p1
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
evnt.misc64B = str.atohex(); // mac_port
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
evnt.misc64A = str.atohex(); // mac_port
evnt.tid = str.atohex(); // dma channel
if (str.match("0x")) str = str.postmatch();
evnt.misc64B = str.atohex(); // num of packets
evnt.misc01A = str.atohex(); // tx_multi_port
if (str.match("0x")) str = str.postmatch();
evnt.misc64C = str.atohex(); // tx_multi_dma_p0
if (str.match("0x")) str = str.postmatch();
evnt.misc64D = str.atohex(); // tx_multi_dma_p1
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
if (str.match("0x")) str = str.postmatch();
evnt.tid = str.atohex(); // RxDmaChnlNo
if (str.match("0x")) str = str.postmatch();
evnt.misc64A = str.atohex(); // RxDescRingLen
if (str.match("0x")) str = str.postmatch();
evnt.misc64B = str.atohex(); // RxRingStartAddr
if (str.match("0x")) str = str.postmatch();
evnt.misc64C = str.atohex(); // RbrConfData
if (str.match("0x")) str = str.postmatch();
evnt.misc64D = str.atohex(); // RxInitKick
evnt.misc01A = str.atohex(); // Xlate
if (str.match("0x")) str = str.postmatch();
evnt.misc64E = str.atohex(); // multi_dma
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
if (str.match("0x")) str = str.postmatch();
evnt.tid = str.atohex(); // RxPktCnt
if (str.match("0x")) str = str.postmatch();
evnt.misc64A = str.atohex(); // iport
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
evnt.tid = str.atohex(); // mac_port
if (str.match("0x")) str = str.postmatch();
evnt.misc64A = str.atohex(); // RxDmaChnlNo
if (str.match("0x")) str = str.postmatch();
evnt.misc64B = str.atohex(); // RxPktCnt
if (str.match("0x")) str = str.postmatch();
evnt.misc64C = str.atohex(); // RxPktLen
evnt.misc01B = str.atohex(); // multi_port
if (str.match("0x")) str = str.postmatch();
evnt.misc64D = str.atohex(); // multi_dma
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) -> marker("text", thisTid, multiShot) bootEnd|goodTrap|badTrap
evnt.routine = items[i]; i++;
evnt.miscStrA = items[i]; i++;
if (str !== "*") evnt.thisTid = str.atohex(); // thisTid
if (str !== "*") evnt.multiShot = str.atohex(); // multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
evnt.miscStrA = items[i]; i++;
if (str !== "*") evnt.multiShot = str.atohex(); // multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
//-----------------------------------------------------------
// Start PCIe link training after boot
//-----------------------------------------------------------
evnt.routine = items[i]; i++;
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
//-----------------------------------------------------------
// Transmit a PCIe Egress command.
// detailed description in
// :/verif/env/fc/vera/classes/asmToVeraIntf.vr
//-----------------------------------------------------------
evnt.routine = items[i]; i++;
evnt.miscStrA = str; // Command type
evnt.misc64A = str.atohex(); // Address
evnt.misc64B = str.atohex(); // length
evnt.misc64C = str.atohex(); // start data. Denali generates incr. data
if (str == "*") evnt.miscStrB = ""; // default value
else evnt.miscStrB = str; // optional errors
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
//-----------------------------------------------------------
// Transmit a PCIe Ingress command.
// detailed description in
// :/verif/env/fc/vera/classes/asmToVeraIntf.vr
//-----------------------------------------------------------
evnt.routine = items[i]; i++;
evnt.miscStrA = str; // Command type
evnt.misc64A = str.atohex(); // Start of Address range
evnt.misc64B = str.atohex(); // End of Address range
evnt.miscStrC = str; // length
evnt.misc64D = str.atohex(); // # of commands
if (str == "*") evnt.miscStrB = ""; // default value
else evnt.miscStrB = str; // optional errors
if (str == "*") evnt.multiShot = 1; // default to always multishot
else evnt.multiShot = str.atohex(); // optional multiShot
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
//////////////////////////////////////////////////////////////////
// ERROR exents in this section
"errCpxPkt": { // ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) -> errCpxPkt(0,0,2)
evnt.routine = items[i]; i++;
evnt.tid = str.atohex(); // match tid
evnt.misc64D = str.atohex(); // pkt type match for err
evnt.misc64C = str.atohex(); // value for error bits
if (str == "*") evnt.misc64A = 0;
else evnt.misc64A = str.atohex(); // optional ifill2 indicator
if (str == "*") evnt.misc64B = 64'hffffffffffffffff;
else evnt.misc64B = str.atohex(); // optional addr to match as well
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
// if (str !== "*") evnt.wait = str.atohex(); // optional wait
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
"errIndicationL2Pkt": { // !$EV trig_pc_d(1, @VA(.MAIN.label_3)) -> errIndicationL2Pkt(3, 2, 1)
evnt.routine = items[i]; i++;
evnt.tid = str.atohex(); // drive tid
evnt.misc64A = str.atohex(); // value to drive for error bits
evnt.misc01A = str.atohex(); // pkt NC field value on error
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
// if (str !== "*") evnt.wait = str.atohex(); // optional wait
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
"errIndicationSOCPkt": { // !$EV trig_pc_d(1, @VA(.MAIN.label_3)) -> errIndicationSOCPkt(3, 2, 1)
evnt.routine = items[i]; i++;
evnt.tid = str.atohex(); // drive tid
evnt.misc64A = str.atohex(); // value to drive for error bits
if (str !== "*") evnt.multiShot = str.atohex(); // optional multiShot
// if (str !== "*") evnt.wait = str.atohex(); // optional wait
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
// The way parameter is overloaded. For ICDP errors it represents the
// inst in which to inject err. ICDP errors are injected in way 0.
// For ICVP, ICTP, and ICMH it represets the way.
// ! $EV trig_pc_d(1,@VA(.MAIN.label)) ->
// IC_hard_err_inj(reg [3:0] err_type, reg [48:0] va, reg [2:0] way, reg [7:0] tid)
evnt.routine = items[i]; i++;
evnt.misc64A = str.atohex(); // err_type
evnt.misc64B = str.atohex(); // address
if (str == "*") evnt.misc64C = 3'h0;
else evnt.misc64C = str.atohex(); // way
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
// ! $EV trig_pc_d(1,@VA(.MAIN.label)) ->
// DC_hard_err_inj(reg [3:0] err_type, reg [6:0] index, reg [1:0] way, reg [7:0] tid)
evnt.routine = items[i]; i++;
evnt.misc64A = str.atohex(); // err_type
evnt.misc64B = str.atohex(); // address
if (str == "*") evnt.misc64C = 2'h0;
else evnt.misc64C = str.atohex(); // way
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) ->
// DTLB_err_enable(reg [2:0] err_type, integer err_freq, reg merr,
// integer burst_len, integer burst_freq,reg [7:0] tid)
// THIS IS AN IMMEDIATE ACTION AT TIME ZERO SO JUST CALL THE FINAL TASK NOW.
evnt.routine = items[i]; i++;
if (str == "*") evnt.misc64A = 3'h7;
else evnt.misc64A = str.atohex(); // err_type = 3'h7
if (str == "*") evnt.miscIntA = -1;
else evnt.miscIntA = str.atoi(); // err_freq = -1
if (str == "*") evnt.misc64B = 2'h3;
else evnt.misc64B = str.atohex(); // merr = 2'h3
if (str == "*") evnt.miscIntB = -1;
else evnt.miscIntB = str.atoi(); // burst_len = -1
if (str == "*") evnt.miscIntC = -1;
else evnt.miscIntC = str.atoi(); // burst_freq = -1
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
asmToVeraIntf.DTLB_err_enable(evnt.misc64A,
#ifdef DEBUGASMEVENTSTOVERA
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) ->
// ITLB_err_enable(reg [2:0] err_type, integer err_freq, reg merr,
// integer burst_len, integer burst_freq,bit [7:0] tid)
// THIS IS AN IMMEDIATE ACTION AT TIME ZERO SO JUST CALL THE FINAL TASK NOW.
evnt.routine = items[i]; i++;
if (str == "*") evnt.misc64A = 3'h7;
else evnt.misc64A = str.atohex(); // err_type = 3'h7
if (str == "*") evnt.miscIntA = -1;
else evnt.miscIntA = str.atoi(); // err_freq = -1
if (str == "*") evnt.misc64B = 2'h3;
else evnt.misc64B = str.atohex(); // merr = 2'h3
if (str == "*") evnt.miscIntB = -1;
else evnt.miscIntB = str.atoi(); // burst_len = -1
if (str == "*") evnt.miscIntC = -1;
else evnt.miscIntC = str.atoi(); // burst_freq = -1
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
asmToVeraIntf.ITLB_err_enable(evnt.misc64A,
#ifdef DEBUGASMEVENTSTOVERA
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) ->
// DC_err_enable(reg [3:0] err_type, integer err_freq, reg merr,
// integer burst_len, integer burst_freq,reg [7:0] tid)
// THIS IS AN IMMEDIATE ACTION AT TIME ZERO SO JUST CALL THE FINAL TASK NOW.
evnt.routine = items[i]; i++;
if (str == "*") evnt.misc64A = 4'hF;
else evnt.misc64A = str.atohex(); // err_type = 4'hF
if (str == "*") evnt.miscIntA = -1;
else evnt.miscIntA = str.atoi(); // err_freq = -1
if (str == "*") evnt.misc64B = 2'h3;
else evnt.misc64B = str.atohex(); // merr = 2'h3
if (str == "*") evnt.miscIntB = -1;
else evnt.miscIntB = str.atoi(); // burst_len = -1
if (str == "*") evnt.miscIntC = -1;
else evnt.miscIntC = str.atoi(); // burst_freq = -1
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
asmToVeraIntf.DC_err_enable(evnt.misc64A,
#ifdef DEBUGASMEVENTSTOVERA
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) ->
// IC_err_enable(reg [3:0] err_type, integer err_freq, reg merr,
// integer burst_len, integer burst_freq,reg [7:0] tid)
// THIS IS AN IMMEDIATE ACTION AT TIME ZERO SO JUST CALL THE FINAL TASK NOW.
evnt.routine = items[i]; i++;
if (str == "*") evnt.misc64A = 4'hF;
else evnt.misc64A = str.atohex(); // err_type = 4'hF
if (str == "*") evnt.miscIntA = -1;
else evnt.miscIntA = str.atoi(); // err_freq = -1
if (str == "*") evnt.misc64B = 2'h3;
else evnt.misc64B = str.atohex(); // merr = 2'h3
if (str == "*") evnt.miscIntB = -1;
else evnt.miscIntB = str.atoi(); // burst_len = -1
if (str == "*") evnt.miscIntC = -1;
else evnt.miscIntC = str.atoi(); // burst_freq = -1
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
asmToVeraIntf.IC_err_enable(evnt.misc64A,
#ifdef DEBUGASMEVENTSTOVERA
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) ->
// STB_err_enable(reg [4:0] err_type, integer err_freq, reg merr,
// integer burst_len, integer burst_freq, reg ue_en,
// integer ce_wt, reg [7:0] tid)
// THIS IS AN IMMEDIATE ACTION AT TIME ZERO SO JUST CALL THE FINAL TASK NOW.
evnt.routine = items[i]; i++;
if (str == "*") evnt.misc64A = 5'h1F;
else evnt.misc64A = str.atohex(); // err_type = 5'h1F
if (str == "*") evnt.miscIntA = -1;
else evnt.miscIntA = str.atoi(); // err_freq = -1
if (str == "*") evnt.misc64B = 2'h3;
else evnt.misc64B = str.atohex(); // merr = 2'h3
if (str == "*") evnt.miscIntB = -1;
else evnt.miscIntB = str.atoi(); // burst_len = -1
if (str == "*") evnt.miscIntC = -1;
else evnt.miscIntC = str.atoi(); // burst_freq = -1
if (str == "*") evnt.misc64C = 2'h3;
else evnt.misc64C = str.atohex(); // ue_en = 2'h3
if (str == "*") evnt.miscIntD = -1;
else evnt.miscIntD = str.atoi(); // ce_wt = -1
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
asmToVeraIntf.STB_err_enable(evnt.misc64A,
#ifdef DEBUGASMEVENTSTOVERA
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) ->
// MRA_err_enable(reg [1:0] err_type, integer err_freq, reg [7:0] mra_entry,
// reg wr_en, integer burst_len, integer burst_freq, reg [7:0] tid)
// THIS IS AN IMMEDIATE ACTION AT TIME ZERO SO JUST CALL THE FINAL TASK NOW.
evnt.routine = items[i]; i++;
if (str == "*") evnt.misc64A = 2'h3;
else evnt.misc64A = str.atohex(); // err_type = 2'h3
if (str == "*") evnt.miscIntA = -1;
else evnt.miscIntA = str.atoi(); // err_freq = -1
if (str == "*") evnt.misc64B = 8'hff;
else evnt.misc64B = str.atohex(); // mra_entry = 8'hff
if (str == "*") evnt.misc64C = 2'h3;
else evnt.misc64C = str.atohex(); // wr_en = 2'h3
if (str == "*") evnt.miscIntB = -1;
else evnt.miscIntB = str.atoi(); // burst_len = -1
if (str == "*") evnt.miscIntC = -1;
else evnt.miscIntC = str.atoi(); // burst_freq = -1
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
asmToVeraIntf.MRA_err_enable(evnt.misc64A,
#ifdef DEBUGASMEVENTSTOVERA
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) ->
// IRF_err_enable(reg [2:0] err_type, integer err_freq, integer ce_wt, reg merr,
// integer burst_len, integer burst_freq,reg [7:0] tid)
// THIS IS AN IMMEDIATE ACTION AT TIME ZERO SO JUST CALL THE FINAL TASK NOW.
evnt.routine = items[i]; i++;
if (str == "*") evnt.misc64A = 3'h7;
else evnt.misc64A = str.atohex(); // err_type = 3'h7
if (str == "*") evnt.miscIntA = -1;
else evnt.miscIntA = str.atoi(); // err_freq = -1
if (str == "*") evnt.miscIntB = -1;
else evnt.miscIntB = str.atoi(); // ce_wt = -1
if (str == "*") evnt.misc64B = 2'h3;
else evnt.misc64B = str.atohex(); // merr = 2'h3
if (str == "*") evnt.miscIntC = -1;
else evnt.miscIntC = str.atoi(); // burst_len = -1
if (str == "*") evnt.miscIntD = -1;
else evnt.miscIntD = str.atoi(); // burst_freq = -1
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
asmToVeraIntf.IRF_err_enable(evnt.misc64A,
#ifdef DEBUGASMEVENTSTOVERA
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) ->
// FRF_err_enable(reg [2:0] err_type, integer err_freq, integer ce_wt, reg merr,
// integer burst_len, integer burst_freq,reg [7:0] tid)
// THIS IS AN IMMEDIATE ACTION AT TIME ZERO SO JUST CALL THE FINAL TASK NOW.
evnt.routine = items[i]; i++;
if (str == "*") evnt.misc64A = 3'h7;
else evnt.misc64A = str.atohex(); // err_type = 3'h7
if (str == "*") evnt.miscIntA = -1;
else evnt.miscIntA = str.atoi(); // err_freq = -1
if (str == "*") evnt.miscIntB = -1;
else evnt.miscIntB = str.atoi(); // ce_wt = -1
if (str == "*") evnt.misc64B = 2'h3;
else evnt.misc64B = str.atohex(); // merr = 2'h3
if (str == "*") evnt.miscIntC = -1;
else evnt.miscIntC = str.atoi(); // burst_len = -1
if (str == "*") evnt.miscIntD = -1;
else evnt.miscIntD = str.atoi(); // burst_freq = -1
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
asmToVeraIntf.FRF_err_enable(evnt.misc64A,
#ifdef DEBUGASMEVENTSTOVERA
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) ->
// SCA_err_enable(integer err_freq, integer ce_wt,
// integer burst_len, integer burst_freq, reg [7:0] tid)
// THIS IS AN IMMEDIATE ACTION AT TIME ZERO SO JUST CALL THE FINAL TASK NOW.
evnt.routine = items[i]; i++;
if (str == "*") evnt.miscIntA = -1;
else evnt.miscIntA = str.atoi(); // err_freq = -1
if (str == "*") evnt.miscIntB = -1;
else evnt.miscIntB = str.atoi(); // ce_wt = -1
if (str == "*") evnt.miscIntC = -1;
else evnt.miscIntC = str.atoi(); // burst_len = -1
if (str == "*") evnt.miscIntD = -1;
else evnt.miscIntD = str.atoi(); // burst_freq = -1
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
asmToVeraIntf.SCA_err_enable(evnt.miscIntA,
#ifdef DEBUGASMEVENTSTOVERA
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) ->
// TSA_err_enable(reg [1:0] err_type, integer err_freq, reg [6:0] tsa_entry,
// reg wr_en, integer ce_wt, integer burst_len, integer burst_freq, reg [7:0] tid)
// THIS IS AN IMMEDIATE ACTION AT TIME ZERO SO JUST CALL THE FINAL TASK NOW.
evnt.routine = items[i]; i++;
if (str == "*") evnt.misc64A = 2'h3;
else evnt.misc64A = str.atohex(); // err_type = 2'h3
if (str == "*") evnt.miscIntA = -1;
else evnt.miscIntA = str.atoi(); // err_freq = -1
if (str == "*") evnt.misc64B = 7'h7f;
else evnt.misc64B = str.atohex(); // tsa_entry = 7'h7f
if (str == "*") evnt.misc64C = 2'h3;
else evnt.misc64C = str.atohex(); // wr_en = 2'h3
if (str == "*") evnt.miscIntB = -1;
else evnt.miscIntB = str.atoi(); // ce_wt = -1
if (str == "*") evnt.miscIntC = -1;
else evnt.miscIntC = str.atoi(); // burst_len = -1
if (str == "*") evnt.miscIntD = -1;
else evnt.miscIntD = str.atoi(); // burst_freq = -1
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
asmToVeraIntf.TSA_err_enable(evnt.misc64A,
#ifdef DEBUGASMEVENTSTOVERA
// ! $EV trig_pc_d(1,@VA(.MAIN.R3_th3r1)) ->
// TCC_err_enable(reg [1:0] err_type, integer err_freq, integer ce_wt,
// integer burst_len, integer burst_freq,bit [7:0] tid)
// THIS IS AN IMMEDIATE ACTION AT TIME ZERO SO JUST CALL THE FINAL TASK NOW.
evnt.routine = items[i]; i++;
if (str == "*") evnt.misc64A = 2'h3;
else evnt.misc64A = str.atohex(); // err_type = 2'h3
if (str == "*") evnt.miscIntA = -1;
else evnt.miscIntA = str.atoi(); // err_freq = -1
if (str == "*") evnt.miscIntB = -1;
else evnt.miscIntB = str.atoi(); // ce_wt = -1
if (str == "*") evnt.miscIntC = -1;
else evnt.miscIntC = str.atoi(); // burst_len = -1
if (str == "*") evnt.miscIntD = -1;
else evnt.miscIntD = str.atoi(); // burst_freq = -1
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
asmToVeraIntf.TCC_err_enable(evnt.misc64A,
#ifdef DEBUGASMEVENTSTOVERA
// L2C_err_enable(bit [5:0] err_type, integer err_freq, integer ce_wt, integer nd_wt
// integer burst_len, integer burst_freq
// THIS IS AN IMMEDIATE ACTION AT TIME ZERO SO JUST CALL THE FINAL TASK NOW.
evnt.routine = items[i]; i++;
if (str == "*") evnt.misc64A = 6'h3F;
else evnt.misc64A = str.atohex(); // err_type = 6'h3F
if (str == "*") evnt.miscIntA = -1;
else evnt.miscIntA = str.atoi(); // err_freq = -1
if (str == "*") evnt.miscIntB = -1;
else evnt.miscIntB = str.atoi(); // ce_wt = -1
if (str == "*") evnt.miscIntC = -1;
else evnt.miscIntC = str.atoi(); // nd_wt = -1
if (str == "*") evnt.miscIntD = -1;
else evnt.miscIntD = str.atoi(); // burst_len = -1
if (str == "*") evnt.miscIntE = -1;
else evnt.miscIntE = str.atoi(); // burst_freq = -1
if (str !== "*") evnt.tid = str.atohex(); // 64 tids // target tid
asmToVeraIntf.L2C_err_enable(evnt.misc64A,
#ifdef DEBUGASMEVENTSTOVERA
// end ERROR events in this section
//////////////////////////////////////////////////////////////////
evnt.routine = items[i]; i++;
evnt.miscStrA = str; //The Name of the register to slam
evnt.misc128A = str.atohex(); // The value to slam the register
if (str !== "*") evnt.tid = str.atohex(); // 64 tids
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
//task watchDebugReg(integer which, integer wait=0,
// integer verbose=0, reg [1:0] checkValue)
evnt.routine = items[i]; i++;
evnt.miscIntA = str.atoi(); // wait
evnt.miscIntB = str.atoi(); // verbose
evnt.miscIntC = str.atoi(); // verbose
if (str !== "*") evnt.misc64A = str.atohex(); // checkValue
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
evnt.routine = items[i]; i++;
if (assoc_index(CHECK, userEventsList, pc)) userEventsList[pc].push(evnt);
else userEventsList[pc] = evnt;
#ifdef DEBUGASMEVENTSTOVERA
userEventsList[pc].printList();
default: error("AsmEventsToVera::parseTrig invalid case!\n");
/////////////////////////////////////////////////////////////////////////
// see what we have to do for this address and do it.
// None of this will make sense until you read:
// Add to the case below to add a new User Event
/////////////////////////////////////////////////////////////////////////
task AsmEventsToVera::serviceEvent(reg [63:0] pc, reg [5:0] fromTid) {
EventClass evntHndlHead = null;
integer remain, notDone=0;
evntHndlHead = userEventsList[pc];
if (evntHndlHead !== null) evnt = evntHndlHead.getHeadEvent();
// keep processing until all events for this address are done
PR_NORMAL (className, MON_NORMAL,
psprintf("serviceEvent: routine = %s, evnt.pc = 0x%0h, evnt.tid = 0x%0h, evnt.tidMask = 0x%0h, fromTid = %0d, passed pc = 0x%0h",
evnt.routine,evnt.pc,evnt.tid,evnt.tidMask,fromTid, pc));
#ifdef DEBUGASMEVENTSTOVERA
"generic_ev" : { // generic user event for general use (6/06)
asmToVeraIntf.generic_ev(evnt.miscStrA,
// if user set thisTid to < 64 then thisTid == fromTid must be true
// else pass over this intp this time.
if (evnt.thisTid >= 64 || evnt.thisTid == fromTid) {
// use evnt.tid if no mask.
// user wants to target only the thread that is at this PC now.
if (evnt.tid > 63) mask = 1 << fromTid;
// dont target non existent tids
mask = mask & enabledTids;
// special value 999 to enable random wait times
if (evnt.wait == 9999) wait = urandom_range(10, 0);
PR_NORMAL (className, MON_NORMAL,
psprintf("serviceEvent: calling intp for tid %0d (mask=%h,wait=%0d)",
#ifdef DEBUGASMEVENTSTOVERA
*, // use bench default. not in use! evnt.src,
} else notDone = 1; // preserve this event
asmToVeraIntf.extint(evnt.wait, evnt.miscIntA);
asmToVeraIntf.cpx_stall(evnt.tid,
// if user set thisTid to < 64 then thisTid == fromTid must be true
// else pass over it this time.
if (evnt.thisTid >= 64 || evnt.thisTid == fromTid) {
PR_ALWAYS("AsmEventsToVera", MON_ALWAYS, evnt.miscStrA);
} else notDone = 1; // preserve this event
asmToVeraIntf.dump_mem(evnt.misc64A,
// SPC BFM will do a store. Pick correct port w/ BFM!!!
asmToVeraIntf.store(evnt.tid,
// Trap conuting Random Error Injection in CCM (L2)
asmToVeraIntf.L2ErrTrapCount(evnt.misc64A);
// Random Error Injection in CCM Data Array
asmToVeraIntf.L2DAErrInjection(evnt.misc64A);
// Random Error Injection in CCM Tag Array
asmToVeraIntf.L2TAErrInjection(evnt.misc64A);
asmToVeraIntf.IosErrInj(evnt.miscStrA,
asmToVeraIntf.IosRandErrInj(evnt.miscStrA,
asmToVeraIntf.siuDmaRd(evnt.misc64A,
asmToVeraIntf.siuDmaWri(evnt.misc64A,
asmToVeraIntf.jtagRdWrL2(evnt.misc64A,
asmToVeraIntf.pktGenConfig(evnt.tid,
asmToVeraIntf.NIU_SetTxMaxBurst(evnt.misc01B,
asmToVeraIntf.NIU_SetTxRingKick(evnt.tid,
asmToVeraIntf.NIU_AddTxChannels(evnt.tid,
asmToVeraIntf.NIU_InitTxDma(evnt.misc01B,
asmToVeraIntf.NIU_TxDMAActivate(evnt.misc64B,
asmToVeraIntf.NIU_EXIT_chk(evnt.misc64B);
asmToVeraIntf.TxPktGen(evnt.misc64A,
asmToVeraIntf.NIU_InitRxDma(evnt.tid,
asmToVeraIntf.NIU_RxPktConf(evnt.tid,
asmToVeraIntf.NIU_RxGenPkt(evnt.tid,
PR_NORMAL (className, MON_NORMAL,
psprintf("serviceEvent: Doing: routine = marker, string = %s, from tid = %0d at pc = 0x%0h",
evnt.miscStrA,fromTid,pc));
asmToVeraIntf.marker(evnt.miscStrA,fromTid,pc);
// special case to improve performance.
// once last thread gets done, allow multiShot event to retire
if (evnt.miscStrA == "bootEnd") {
// printf("%0d outOfBoot = 0x%h\n",get_time(LO),outOfBoot);
if (outOfBoot == enabledTids) {
if (evnt.miscStrA == "bootStart") {
// printf("%0d startBoot = 0x%h\n",get_time(LO),startBoot);
if (startBoot == enabledTids) {
asmToVeraIntf.reset_now(evnt.miscStrA);
asmToVeraIntf.set_StartPEUTest();
asmToVeraIntf.EnablePCIeEgCmd(evnt.miscStrA,
asmToVeraIntf.EnablePCIeIgCmd(evnt.miscStrA,
asmToVeraIntf.errCpxPkt(evnt.tid,
asmToVeraIntf.IC_hard_err_inj(evnt.misc64A,
asmToVeraIntf.DC_hard_err_inj(evnt.misc64A,
asmToVeraIntf.errCpxPkt(evnt.tid,
asmToVeraIntf.errCpxPkt(evnt.tid,
asmToVeraIntf.registerSlam(evnt.miscStrA,
asmToVeraIntf.watchDebugReg(evnt.miscIntA, evnt.miscIntB,
evnt.miscIntC, evnt.misc64A);
asmToVeraIntf.spc_warm_reset();
default: error("AsmEventsToVera::serviceEvent invalid case!\n");
if (eventsNeverDone) notDone = 1; // for reset testing. Code will repeat.
evnt = evntHndlHead.getNextEvent(remain,notDone,eventCount);
// kill off this PC's list, we are all finished with it
userEventsList[pc].delete();
userEventsList[pc] = null;
assoc_index (DELETE, userEventsList, pc);
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
task AsmEventsToVera::new(StandardDisplay dbg,
this.enabledTids = enabledTids;
listLock = alloc(SEMAPHORE, 0, 1, 1);
#ifdef DEBUGASMEVENTSTOVERA
if (mChkPlusarg(eventsNeverDone)) eventsNeverDone = 1;
else eventsNeverDone = 0;
probes[0] = asmEventCore0;
probes[1] = asmEventCore1;
probes[2] = asmEventCore2;
probes[3] = asmEventCore3;
probes[4] = asmEventCore4;
probes[5] = asmEventCore5;
probes[6] = asmEventCore6;
probes[7] = asmEventCore7;
probes[8] = asmEventCore8;
probes[9] = asmEventCore9;
probes[10] = asmEventCore10;
probes[11] = asmEventCore11;
probes[12] = asmEventCore12;
probes[13] = asmEventCore13;
probes[14] = asmEventCore14;
probes[15] = asmEventCore15;
probes[16] = asmEventCore16;
probes[17] = asmEventCore17;
probes[18] = asmEventCore18;
probes[19] = asmEventCore19;
probes[20] = asmEventCore20;
probes[21] = asmEventCore21;
probes[22] = asmEventCore22;
probes[23] = asmEventCore23;
probes[24] = asmEventCore24;
probes[25] = asmEventCore25;
probes[26] = asmEventCore26;
probes[27] = asmEventCore27;
probes[28] = asmEventCore28;
probes[29] = asmEventCore29;
probes[30] = asmEventCore30;
probes[31] = asmEventCore31;
probes[32] = asmEventCore32;
probes[33] = asmEventCore33;
probes[34] = asmEventCore34;
probes[35] = asmEventCore35;
probes[36] = asmEventCore36;
probes[37] = asmEventCore37;
probes[38] = asmEventCore38;
probes[39] = asmEventCore39;
probes[40] = asmEventCore40;
probes[41] = asmEventCore41;
probes[42] = asmEventCore42;
probes[43] = asmEventCore43;
probes[44] = asmEventCore44;
probes[45] = asmEventCore45;
probes[46] = asmEventCore46;
probes[47] = asmEventCore47;
probes[48] = asmEventCore48;
probes[49] = asmEventCore49;
probes[50] = asmEventCore50;
probes[51] = asmEventCore51;
probes[52] = asmEventCore52;
probes[53] = asmEventCore53;
probes[54] = asmEventCore54;
probes[55] = asmEventCore55;
probes[56] = asmEventCore56;
probes[57] = asmEventCore57;
probes[58] = asmEventCore58;
probes[59] = asmEventCore59;
probes[60] = asmEventCore60;
probes[61] = asmEventCore61;
probes[62] = asmEventCore62;
probes[63] = asmEventCore63;
////////////////////////////////////////////////////////////////
// read diag.ev file and build up sync routine.
////////////////////////////////////////////////////////////////
// N1 calls as: read_vera_tasks("diag.ev", 0, "", "");
task AsmEventsToVera::readEventFile(string file,
string line, items[ITEMCOUNT];
if (mChkPlusarg(noUserEvents)) {
printf("%9d: AsmEventsToVera[]: +noUserEvents detected. AsmEventsToVera class dissabled!\n", get_cycle());
fp = fopen(file, "r", SILENT);
line = freadstr(fp, SILENT);
if (line.match("printhex")) continue;
if (line.match("printdec")) continue;
if (line.match("^\s*$")) continue;
if (line.match("^\s*//")) continue;
// Do not process N1 errors
// or we end up with garbage in list! jp
if (line.match("error(")) continue;
// seperates fields by ( and comma, always excluding any 64'h
this.extract(line, items);
if (items[0] == "trig_pc_d") parseTrig(items);
printf("AsmEventsToVera::readVeraTasks ERROR: This stuff is bad ->");
for (i=0;i<ITEMCOUNT;i++) if (items[i] != null) printf("%s \n",items[i]);
error("AsmEventsToVera::readVeraTasks ERROR: invalid user event found in file %s\n",file);
// if no events, do nothing.
if (assoc_index(FIRST, userEventsList, tmp64)) {
eventCount = userEventsList[tmp64].getEventCount();
asmToVeraIntf = new(); // Each bench's $EVENTs implementation tasks
fork mainMonitor(); join none
////////////////////////////////////////////////////////////////
// parse line, used by readVeraTasks
////////////////////////////////////////////////////////////////
// trig_pc_d(0,64'h0000000020000d90) -> intp(0, 0, 3a)
// error(0,64'h0000000020000d90,1,IRF,ce,8,x, x,x,x, x,x,x)
task AsmEventsToVera::extract(string str, var string items [ITEMCOUNT]) {
#ifdef DEBUGASMEVENTSTOVERA
if (debug) printf("\nExtract: input=%s\n",str);
for (i=0;i<ITEMCOUNT;i++) items[i] = "*";
// seperates fields by ( and comma, always excluding any 64'h
while(str.match("\s*(64'h)*([\w\*]+)"))
items[i] = str.backref(1); //str_list.push_back(str.backref(1));
#ifdef DEBUGASMEVENTSTOVERA
printf("Extract:push_backA: [%0d] %s\n", i, items[i]);
if(str.match("^\(\s*\"")){
items[i] = str.prematch(); // str_list.push_back(str.prematch());
#ifdef DEBUGASMEVENTSTOVERA
printf("Extract:push_backB: [%0d] %s\n", i, items[i]);
// watch for instruction completion, get address, check hash.
// if user event is dumping a register, get CWP and reg too.
// Uses new() input enabledTids to determine which threads to monitor.
task AsmEventsToVera::mainMonitor() {
integer i, maxTidBit=64, minTidBit=0, serviceTime;
reg [63:0] pc, localReady;
repeat (2) @(posedge probes[0].$clk);
if (mChkPlusarg(noUserEvents)) {
printf("%9d: AsmEventsToVera[]: +noUserEvents detected. AsmEventsToVera class dissabled!\n", get_cycle());
printf("%9d: AsmEventsToVera[]: $EV User Events detected. Input enabledTids=0x%h\n", get_cycle(), enabledTids);
if (! enabledTids) printf("%9d: AsmEventsToVera[]: $EV User Events enabledTids is 0! No User Events will happen!\n", get_cycle());
// printf("%0d AsmEventsToVera: core_running_status 0x%h\n",
// get_cycle(),asmEventsToVera_if.core_running_status);
for (i=0;i<64;i++) if (enabledTids[i]) maxTidBit = i;
for (i=63;i<=0;i--) if (enabledTids[i]) minTidBit = i;
// printf("%0d AsmEventsToVera: while loop waiting for readies\n", get_cycle());
@(asmEventsToVera_if.ev_ready); // wait for any change
// printf("%0d AsmEventsToVera: outer while loop see a ready\n", get_cycle());
while (asmEventsToVera_if.ev_ready) { // any high/staying high?
localReady = asmEventsToVera_if.ev_ready;
// printf("%0d AsmEventsToVera: inner while loop still see ready: %h\n", get_cycle(),localReady);
for (i=minTidBit;i<=maxTidBit;i++) {
if (enabledTids[i] && localReady[i]) {
#ifdef DEBUGASMEVENTSTOVERA
printf("%0d AsmEventsToVera: TID %0d @%0d ready = %b pc = 0x%h\n",
get_cycle(), i, get_time(LO), localReady[i],pc[43:0]);
// check the hash w/ this pc and serviceEvent.
// only do one thread at a time.
if (assoc_index(CHECK, userEventsList, pc)) {
serviceTime = get_time(LO);
if (serviceTime != get_time(LO))
printf("\nERROR: When servicing an event, time advanced (from %0d to %0d).\nThis will cause events to be missed. Advancing time is not allowed.\nKeep in mind that checking and driving interfaces CAN advance time!!!\nCheck your asmToVeraIntf.vr file - use forks as needed.\n",serviceTime,get_time(LO));
@(negedge probes[0].$clk);
@(negedge probes[0].$clk);
printf("%0d: AsmEventsToVera: All User Events consumed, no child threads, goodbye.\n", get_cycle());
} // while ready continues back to back
wait_child(); // overkill
} // while waiting for a ready