pulp-platform / riscv-dbg

RISC-V Debug Support for our PULP RISC-V Cores
Other
197 stars 70 forks source link

Timing of DMI req/rsp signals #166

Open rswarbrick opened 2 weeks ago

rswarbrick commented 2 weeks ago

I've spent a rather confusing couple of hours trying to diagnose behaviour that I'm seeing in OpenTitan. There, we have a frontdoor agent that does DMI transactions as follows:

The "short time" that is currently in the agent is 10 TCK cycles. But this is not really enough. Specifically, the CDC component (i_dmi_cdc in dap) takes a reasonable time for the dmi_resp_i signal to be synchronised to dmi_resp in dmi_jtag.sv. This timing depends on the implementation of prim_fifo_async_simple.

In an example test that I've just run, the time from the end of the first JTAG transaction to when dmi_resp_valid goes high in dmi_jtag is 13 TCK cycles. Here's a screenshot of waves that show this: image

Unfortunately, the OpenTitan frontdoor didn't wait long enough (because of the 10 TCK cycles above). The result is that the "nop" JTAG transaction starts too early and the CaptureDr JTAG state happens a cycle before the response comes back. The end result is that our frontdoor agent thinks the DMI operation is complete, but then gets rather confused when it sees a "busy" response in the next JTAG transaction it sends.

There's a trivial short-term workaround: to increase the "short time" that we wait in the DV agent. (I'm going to do that). But I'm a bit confused: is there a minimum number of clk/TCK cycles between request and reading the response? (And is it described anywhere?) If not, maybe it makes sense to make things a bit more robust by treating an operation as being in progress from when the req goes out to when the response comes back.

rswarbrick commented 2 weeks ago

Oh! I've just realised that the implausibly large delay is caused by the fact that TCK is not being toggled (so the CDC takes a long time!). So there's an easy workaround on the OpenTitan side: make sure that TCK is being toggled in that time.

The result ends up being a 4 cycle wait between request and response, which is much more sensible! But I think my question in the last paragraph still stands.

bluewww commented 2 weeks ago

But I'm a bit confused: is there a minimum number of clk/TCK cycles between request and reading the response? (And is it described anywhere?)

I don't think we have documented anything like that. Usually, we have logic that does an exponential (or linear) backoff whenever we hit "busy" as is described in the spec.

If not, maybe it makes sense to make things a bit more robust by treating an operation as being in progress from when the req goes out to when the response comes back.

I'm confused. Shouldn't that be the case already?

rswarbrick commented 2 weeks ago

I'm thinking about the following sequence:

From the outside agent's point of view, it sees: