JTAG_DMI UVM Agent
JTAG_DMI UVM Agent is extended from DV library agent classes. Contrary to what the name suggests, it actually does not come with an agent. It is called an agent because it comes with a monitor, an RAL model and a RAL frontdoor accessor class, wrapped in a package that provides some additional utility methods.
Block diagram
jtag_dmi_item
This class represents a predicted DMI transaction, captured by the monitor.
It consists of req_op
, addr
, wdata
, rsp_op
and rdata
. The first three
captures a DMI request as initiated by the host, whereas the last two capture
the response type and read data respectively.
jtag_dmi_monitor
This component converts the raw JTAG transactions captured from the
jtag_monitor
in the jtag_agent
over its TLM analysis port into a stream of
jtag_dmi_item
transactions which are sent over this component’s analysis
port. A JTAG DMI access is made by writing to the JTAG DTM DMI register with
the request, and polling it subsequently for completion. This monitor analyzes
the incoming raw JTAG transactions to see if the JTAG DMI register was
accessed, by matching the IR value. If it was, then it captures the subsequent
updates to its DR to extract the predicted DMI requests. It uses the JTAG DTM
RAL model to parse the DTM DMI register fields from these writes and reads.
Likewise, it examines the dout
value of the transaction item (i.e. the read
value of the DTM DMI register) which indicates the status of the previously
initiated DMI request, as well as the read data. Partial requests are
immediately written to the req_analysis_port
and are held in a local queue.
When it detects that the access completed, it pops the partial request from the
queue, updates the request with the response information, and writes the
completed transaction to the analysis_port
.
Note that these transactions are predictions, based on reads and writes to the JTAG DTM register. The actual internal DMI interface is not probed.
Any raw JTAG transactions that were not made to the JTAG DTM DMI register are
passed through the non_dmi_jtag_dtm_analysis_port
.
This monitor is required to be instantiated alongside the jtag_agent
in the
testbench environment that seeks to consume the captured JTAG DMI transactions.
jtag_dmi_reg_block
This class represents the JTAG DMI register space, as indicated in the RISCV
debug specification 0.13.2.
The registers were specified in the adjoining jtag_dmi.hjson
file and
converted to the model using our reggen
tool. It has been hand-edited after generation to remove the comportability
assumptions. See the notes in the file for details.
The package provides a convenience function
jtag_dmi_agent_pkg::create_jtag_dmi_reg_block()
that creates and returns
a handle to this model. It also attaches the frontdoor accessor class to
all registers, which replaces the traditional access of registers using a
map and an adapter. Like the JTAG DMI monitor, an object of this class is
also required to be manually instantiated in the parent environment.
This register model serves to be generic in nature. It does not cater to a specific implementation. The actual implementation of this register space may differ in the design. The reset values and access policies of these registers may need to be altered in the parent environment before use, based on the implementation.
jtag_dmi_reg_frontdoor
Accesses to the DMI register space over JTAG happen indirectly via writes
to the DTM register called dmi
which is specified in the
jtag_dtm_reg_block
provided by the jtag_agent
. Hence, the accesses to the
DMI register space cannot be made via the traditional register map and adapter
method. This sequence writes the DTM dmi
register to issue a DMI read or
a write request, then polls it for completion. The DTM dmi
register
on subsequent reads, indicates the status of the request (success, busy or
fail), in addition to the read data. If the request status is busy, it keeps
polling, until either a JTAG reset (trst_n
) asserts or a timeout occurs.
It uses an externally created semaphore jtag_dtm_ral_sem_h
to atomicize
accesses to the DTM dmi
register, since accesses to all DMI registers go
through this shared resource. This semaphore is also created and set by the
convenience function jtag_dmi_agent_pkg::create_jtag_dmi_reg_block()
.
sba_access_item
This class represents the driven or predicted SBA transaction. It is used by
the routines provided in jtag_rv_debugger_pkg
, as well as by the
sba_access_monitor
. It contains request and response related fields. It also
has special control knobs to modify the behavior of the design when initiating
accesses. These knobs - readonaddr
, readondata
, and autoincrement
are
written to the SBCS register, if different from the defaults.
sba_access_monitor
This monitor retrieves the predicted JTAG DMI transactions from the
jtag_dmi_monitor
to further analyze accesses to the SBA subset of the DMI
register space, using the handle to the jtag_dmi_reg_block
instance, which is
set externally. It examines the stream of reads and writes to the SBA registers
to predict outgoing SBA transactions. For this prediction to work correctly,
the stimulus needs to be sent correctly as well, which is facilitated by the
routines provided by the jtag_rv_debugger_pkg
.
Any JTAG DMI transactions that were not made to the SBA registers are passed
through the non_sba_jtag_dmi_analysis_port
.
This monitor is required to be instantiated alongside the jtag_agent
in the
testbench environment that seeks to consume the predicted SBA transactions.
jtag_rv_debugger
The JTAG DMI register space has registers to initiate and manage accesses into
the system through an external system bus (whatever that may be). Please see the
RISCV debug specification for more details. These registers are already
a part of the jtag_dmi_reg_block
model.
This class models an external debugger by providing methods to perform debug activies such as issuing CPU halt request, non-debug domain reset request, run abstract commands to access CPU registers and the system memory, inserting breakpoints, single-stepping, injecting programs into SRAM and having the CPU starting fetching instructions from arbitrary memory locations. It also provides methods to initiate and manage accesses into the system bus access interface (SBA) using these SBA registers, including starting an access, waiting for completion and clearing the error bits.