I'm trying to debug a failure that's showing up in "rv_dm", a small wrapper around the riscv-dbg module in OpenTitan. The issue comes up when the JTAG clock is being driven at a higher frequency than the system clock.
The JTAG-based DMI agent sends a request (DTM_WRITE). A short time later, it sends another JTAG message with request DTM_NOP. The response in that second JTAG transaction is DTM_SUCCESS, which the agent interprets as meaning that the write operation has completed. When we send another JTAG message, we get a response of DTM_BUSY and everything is very confused: what were we busy with?!
Here is a screenshot of the waves that we see:

The timing comes out as:
- 39,855ns:
- End of JTAG for
DTM_WRITE request
dmi_req_valid in dmi_jtag goes high to send DMI request to debug module
- 39,968ns: Start of second JTAG transaction
- 39,995ns:
- TAP goes to
CaptureDr (and capture_o goes high)
dr_d in the DTM gets filled with DMINoError
- 40,697ns: End of JTAG(2) with
DTM_SUCCESS response (from the DMINoError)
I'm a bit surprised that there isn't a "busy" status that we put into dr_d when the DTM is still in the WaitWriteValid FSM state. But maybe I'm missing some other method of synchronisation that the agent could be using.
What's wrong here? :-)
I'm trying to debug a failure that's showing up in "rv_dm", a small wrapper around the
riscv-dbgmodule in OpenTitan. The issue comes up when the JTAG clock is being driven at a higher frequency than the system clock.The JTAG-based DMI agent sends a request (DTM_WRITE). A short time later, it sends another JTAG message with request DTM_NOP. The response in that second JTAG transaction is DTM_SUCCESS, which the agent interprets as meaning that the write operation has completed. When we send another JTAG message, we get a response of DTM_BUSY and everything is very confused: what were we busy with?!
Here is a screenshot of the waves that we see:

The timing comes out as:
DTM_WRITErequestdmi_req_validindmi_jtaggoes high to send DMI request to debug moduleCaptureDr(andcapture_ogoes high)dr_din the DTM gets filled withDMINoErrorDTM_SUCCESSresponse (from theDMINoError)I'm a bit surprised that there isn't a "busy" status that we put into
dr_dwhen the DTM is still in theWaitWriteValidFSM state. But maybe I'm missing some other method of synchronisation that the agent could be using.What's wrong here? :-)