The constructor passes its arguments to the base class. It then associates the JTAG target port with its handler and clears the mutex.
// Bind the handler to the JTAG target port. jtag.register_b_transport( this, &Or1ksimJtagSC::jtagHandler ); // Unlock the Mutex or1ksimMutex.unlock ();
The implementation of the run
method is very
similar to the base class for temporally decoupled models (see Section 9.4.3). However the call to
or1ksim_run
is surrounded by lock/unlock of the
mutex to ensure it cannot run at the same time as a thread
requesting JTAG access.
or1ksimMutex.lock (); (void)or1ksim_run (timeLeft.to_seconds ()); or1ksimMutex.unlock ();
The handler for JTAG transactions attempts to determine the type and exact bit size of the register from the extension payload. If this is not present (it is an ignorable extension), then it uses the generic payload address and data length instead.
// Retrieve the extension. JtagExtensionSC *ext; payload.get_extension (ext); // Check if the extension exists. Set up the access type and bit size as // appropriate. JtagExtensionSC::AccessType type; int bitSize; if (NULL == ext) { unsigned int addr = (unsigned int) payload.get_address (); type = (ADDR_SHIFT_IR == addr) ? JtagExtensionSC::SHIFT_IR : (ADDR_SHIFT_DR == addr) ? JtagExtensionSC::SHIFT_DR : JtagExtensionSC::RESET ; bitSize = 8 * (int) payload.get_data_length (); } else { type = ext->getType (); bitSize = ext->getBitSize (); }
The handler then calls the appropriate function in the Or1ksim
ISS, surrounding the call by a mutex lock/unlock, to ensure that
JTAG transactions are not processed while the ISS is
running. This could occur if an upcall caused a
wait ()
allowing processing of a JTAG
transaction to occur.
The implementation of the Or1ksim ISS wrapper module class with
JTAG debug support, Or1ksimJtagSC
may be
found in sys-models/jtag-soc/Or1ksimJtagSC.cpp
in the distribution.