This issue is really difficult to reproduce, but o...
# gf180mcu
t
This issue is really difficult to reproduce, but one very consistent way is to do a wishbone access directly after the variable assignment. It HAS to be into the user project part of the address range, though. See this gist for an example, but you'll have to change the address used for the wishbone write to a user project area wishbone endpoint on your chip https://gist.github.com/89Mods/d60340636f66a60978492da2c6ea92c1
d
Does the wishbone have a fail-safe timeout (watchdog) if the device being addressed does not accept the outstanding transaction ? Is there a way to detect if this is triggered ? Adding the
lw zero,(zero)
immediately after every write to variable, and immediately after any write to wishbone, and immediately before call to
delay()
look like the hot zones to force the CPU write-back to flush when you expect things to happen in program order then maybe comment out the write to user project wishbone address, to see if the rest of the program performs as you expect. Then re-introduce WB write to see if misbehave ? The variable assignment may appear to get forgotten, if the CPU writeback store (remained outstanding) at the time the WB MMIO write occurred and that locked up the WB ? and watchdog recovery took effect ? I am positing if this is a possible scenario indicating the user_module WB is not accepting/responding to transactions issued to it.
FWIW the
lw zero,(zero)
matter I more fully described before, is related to the sequence of events: • load/stores occurs (lw/sw) • a final store occurs (that the timing of when it is committed is important to operation), for example an MMIO write to start an operation with user_project • then a long sequence of instructions occur, that is pure computation (no load, no store, all register based, can contain branches and loops and overflows cache) • an example of
for(int i=0, i<1000000; i++) { nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop }
what I call a tight delay loop, I exaggerate nop count to demonstrate a sequence that exceed cache size • the last store can still remain outstanding inside the write-back of the CPU waiting for WB bus arbitration to commit be able to commit, but because the CPU instruction fetch has arbitration and because it is always hungry, due to slow flash, fast CPU, speculative fetching, it never releases it • adding the no-op
lw zero,(zero)
causes the CPU to stall until the write-back is committed, so it stops executing instructions, which releases instruction fetch over xip/spi from wishbone, allowing Vex WB arbiter to switch to service outstanding write-back of data Your example program by contrast is a continuous stream of load/store, even inside delay(), even printf() is getting and putting data somewhere. So it does not look like it is affect by the above scenario. But if you observe a difference in behaviour this does indicate it is related to the CPU write-back not getting committed over WB. Hence I suggest it maybe due to WB error recovery after a WB lockup (maybe due to no ACK_I signal from user_project) so the WB transaction integrity is lost during a recovery process.
t
@dlmiles: The GF processor implementation is the same as the sky130 one except for limitation of memory due to limitation of chip area. But the sky130 version definitely has a timeout on wishbone accesses, and it is very easy to detect by running a long LED blink loop with a memory access in the middle of the loop. When it is timing out, the loop time is hundreds of times longer than when it doesn't.
a
@dlmiles I'm late to the party, but... the Wishbone timeout is 1,000,000 cycles (can be found in the LiteX code, I think written as
1e6
). A timed out read will return
0xFFFFFFFF