The class is declared as having a dynamic process, since the constructor will set up a SystemC thread.
SC_HAS_PROCESS (JtagLoggerSC);
The constructor passes the module name up to the base class. It associates the payload extension instance with the generic payload instance. Finally it declares a new SystemC thread.
We must use a SC_THREAD
rather than
SC_METHOD
since the thread method,
runJtag
will wait ()
for one second between each read of the next program counter.
payload.set_extension (&ext); SC_THREAD (runJtag);
The main thread method, runJtag
uses the
various support utilities to construct JTAG registers which are
then transported to the target wrapped ISS
First the JTAG reset, instruction and module selection are shifted, each followed by a message, noting how long the step took.
jtagReset (delay); cout << "Reset after " << delay << "." << endl; wait (SC_ZERO_TIME); delay = SC_ZERO_TIME; jtagInstruction (DEBUG_INST, delay); cout << "Instruction shifted after " << delay << "." << endl; wait (SC_ZERO_TIME); delay = SC_ZERO_TIME; jtagSelectModule (CPU0_MOD, delay); cout << "Module selected after " << delay << "." << endl; wait (SC_ZERO_TIME);
A wait for zero time between each transaction ensures any other thread has an opportunity to resume if needed.
The main loop reads the next program counter, waiting for one second
between each loop. The read involves two transactions, one
WRITE_COMMAND
to specify the transfer required,
one GO_COMMAND
to accomplish the transfer.
while (true) { // Specify the WRITE_COMMAND to read the NPC SPR delay = SC_ZERO_TIME; jtagWriteCommand (READ32, SPR_NPC, 4, delay); cout << "WRITE_COMMAND after " << delay << "." << endl; wait (SC_ZERO_TIME); // Read the data, remembering that OR1200 is big endian unsigned char res[4]; // For the data read back delay = SC_ZERO_TIME; jtagGoCommandRead (res, 4, delay); cout << "GO_COMMAND after " << delay << "." << endl; cout << "- NPC = 0x" << hex << (int) res[3] << (int) res[2] << (int) res[1] << (int) res[0] << dec << "." << endl; wait (sc_time (1000.0, SC_MS)); }
The utilities to help in constructing registers and passing them to the target are largely concerned with the minutiae of format. In each the register is constructed, transported to the target and the returned register analyzed.
The implementation of the JTAG logger module class,
JtagLoggerSC
may be found in
sys-models/jtag-soc/JtagLoggerSC.cpp
in the
distribution.