kuznia-rdzeni / coreblocks

RISC-V out-of-order core for education and research purposes
https://kuznia-rdzeni.github.io/coreblocks/
BSD 3-Clause "New" or "Revised" License
35 stars 13 forks source link

Wishbone slave memory #103

Closed Kristopher38 closed 1 year ago

Kristopher38 commented 1 year ago

Currently we don't have a wishbone slave implementation, which is required if we want to perform any memory accesses. I've researched our options with regards to fixing this and they're as follows (in no particular order):

  1. amaranth-soc, particularly with this PR. Written in amaranth, implements wishbone interface and some handy features like memory maps that we won't need for now, but the PR specifically implements a bridge between "SRAM bus" (bus with raw memory signals like data, addr, w_en, r_en etc.) and wishbone. Minimal glue-code would be needed to get it running (or at least I think so from a brief look at the source).
  2. litex's version of wishbone SRAM. Written in migen, so it would need to be ported over (without bursting it should be minimal effort?) to amaranth since I'm told that it can't directly interface with migen (not without dumping either of them into verilog first). Choosing this would probably mean writing a few extra tests in addition to the ones which we would port over from litex, since as far as I can see they only test bursting.
  3. Rolling our own wishbone slave - looking at the PR mentioned in 1., specifically here, and litex's version here (where the actual transaction happens) makes me think implementing wishbone memory wishbone slave isn't as hard as it first seemed, especially when we're not doing anything fancy like supporting multiple memory segments or bursting.

I looked at using cocotb as was first suggested. Main problem I have with using it is that it works on verilog. so we'd need to dump our design to it first and test on that. There's integration with amaranth but it dumps to verilog anyway. We'd also lose the ability to do in-python debugging and possibly debugging with vcd dumps would be harder since we would be operating on amaranth-generated signal names. We should not pursue this route.

I'd like to hear your thoughts on this, especially from @tilk. I think bringing code mentioned in 1. is a bit of an overkill for the features we need, and we're capable of doing some blend of options 2. and 3. - writing our own slave while referencing litex's code in the process.

tilk commented 1 year ago

I essentially agree with your assessment of the situation. We currently don't use advanced features of Wishbone like bursting - which will be important later, for caches and DRAMs. So the task is not too complex, and we can roll out our own slave. The code you linked (LiteX and amaranth-soc) are both BSD licensed, so using them for reference is okay.

I agree that cocotb is not the solution we want (at least for now), for reasons you mentioned. I think it might prove useful later, when we will be running larger tests in CI (for example, the official RISC-V testbench) on the finished core, as cocotb is capable of utilziing Verilator. Amaranth's internal simulator might be too slow for that.

wkkuna commented 1 year ago

Personally, I would head more to having own Wishbone slave implementation. I agree that importing amaranth-soc seems a bit too much for our needs and may cause some unnecessary dependencies. As for LiteX's SRAM, maintaining and incorporating generated-verilog sources appears to be more troublesome than implementing our own.

As for more references, I could add that at zipcpu there's minimal wishbone slave example (in verilog) well explained.

When it comes to referencing other projects I think it's also important to simultaneously check the wishbone specification to make sure what parts are guaranteed/required.