Skip to content

[Monitor + Interp] Wishbone subordinate example#193

Merged
ekiwi merged 30 commits intomainfrom
wishbone_example
Feb 26, 2026
Merged

[Monitor + Interp] Wishbone subordinate example#193
ekiwi merged 30 commits intomainfrom
wishbone_example

Conversation

@ngernest
Copy link
Contributor

@ngernest ngernest commented Feb 19, 2026

This PR adds a test case containing a Wishbone subordinate. The Makefile, C++ testbench and Verilog files (in the interpreter's test for this example) are taken from:

(with minor modifications so that Verilator works on M-series Macs)

The VCD file is produced by their test-bench.

The monitor infers the following trace from the VCD:

// trace 0
trace {
    read(0, 0);
    write(0, 0);
    read(0, 3);
    read(0, 5);
    read(0, 7);
    read(0, 9);
    read(0, 11);
    read(0, 0);
    write(0, 0);
    read(0, 3);
    read(0, 5);
    read(0, 7);
    read(0, 9);
    read(0, 11);
    read(0, 0);
}

This mostly matches the .tx file supplied to the interpreter (the only difference is that the two writes in the .tx file are write(0, 1) instead of write(0, 0)). There are some differences between the interpreter and their test-bench which I've been unable to figure out, so we should exclude this example from the round-trip tests.

Side-note about stall and ack

Note: in the write protocol, we only wait till ack becomes 1, like so:

// Wait until Ack becomes 1 
// (`stall` becomes 1 in the same cycle as `ack`, so we don't wait for it in a separate loop) 
while (DUT.o_ack == 1'b0) {
    step();
} 
...

We don't need to wait for stall to become 0 in a separate while-loop, because the spec for Wishbone B4 Pipeline mode allows for ack and stall to change at the same time. In this particular Verilog DUT, stall and ack are both 1 in the same cycle (the ack = 1 means the current request has been serviced, whereas stall = 1 indicates that the next request has to wait).

If instead we had written the following, this would be wrong:

// Wait for stall to become 0, then wait for ack to become 1
// This is wrong, since `stall` and `ack` can be updated at the same time
while (DUT.o_stall == 1'b1) { 
  step(); 
}
while (DUT.o_ack == 1'b0) { 
  step(); 
}

The reason why this is wrong is that since stall and ack can be updated at the same time, if we waited for them sequentially (one after another), we would miss a ack = 1 that could have arrived when we still had stall = 1.

Thus, in the write protocol in this PR, we only wait for ack to become 1.

@ngernest ngernest changed the title (WIP) Buggy Wishbone subordinate example (WIP) Wishbone subordinate example Feb 26, 2026
@ngernest ngernest changed the title (WIP) Wishbone subordinate example [Monitor + Interp] Wishbone subordinate example Feb 26, 2026
@ngernest ngernest marked this pull request as ready for review February 26, 2026 16:08
@ngernest ngernest requested a review from ekiwi February 26, 2026 16:41
@ngernest
Copy link
Contributor Author

ngernest commented Feb 26, 2026

Some possible next steps for expanding the Wishbone case-study further:

  1. Compare our interpreter + monitor to a Cocotb driver/monitor for Wishbone subordinates using the following:
  1. There is a benchmark suite for Wishbone interconnects, described in a blogpost (2nd link below), it could be interesting to see if our monitor works on the waveforms produced by DUTs under the workloads in the benchmark

@ekiwi ekiwi merged commit e3afb5b into main Feb 26, 2026
16 checks passed
@ngernest ngernest deleted the wishbone_example branch February 26, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants