Closed wallento closed 6 years ago
@ccelio The memory is generated by Chisel, right? Does it also generate some DPI functions along with it? If not its worth suggesting it.
@wallento this is where the scratchpad memory is instantiated:
https://github.com/librecores/riscv-sodor/blob/master/src/common/memory.scala#L88
Also notice there's an extra wrinkle of complication -- the memory is banked (because the HTIF protocol wrote 8 byte chunks but the core only reads in 4 byte chunks). I think @codelec should probably remove the banking. For starters, it will make initializing the scratchpad memory easier.
Is SeqMem transformed to a simple memory in FIRRTL? (Sorry, I hope you simply know, otherwise I can look it up too)
If that is the case we may suggest adding some complexity to the Verilog emitter and provide the configuration option to write SystemVerilog with DPI here: https://github.com/ucb-bar/firrtl/blob/master/src/main/scala/firrtl/Emitter.scala#L612
This seems kind of the cleanest way for me.
Ah, maybe its even more clean to add an extra FIRRTL transform that creates a blackbox and put the systemverilog file into the sources. I will need to check how easy it can be hooked in and if this is useful to a broader community in which case the other solution is maybe preferable.
I'm not fully familiar with how SeqMem's are handled, except to say that (with a --repl-seq-mem
flag to firrtl) they are blackboxed (so you can use your foundry's SRAM model in its place).
Example invocation:
https://github.com/freechipsproject/rocket-chip/blob/master/vsim/Makefrag-verilog#L17
Ah, I see. Then we should maybe try this option and use a simple System Verilog + DPI memory module for the blackbox. This is the best option for Verilator I think.
I've proposed some Chisel support to help with this: https://github.com/ucb-bar/chisel3/issues/609
In effect, this wouldn't provide DPI functions or anything but would provide the information necessary to easily generate it. I agree that initializing memories is such a common thing in simulation that perhaps it should have additional supports on top though.
Thanks @jackkoenig, that is indeed also very useful! Verilator works fine with hierarchical wiring and it should be possible to have the DPI in the testbench top then.
One slight disadvantage of this approach is that the DPI is not in the scope of the module then and in the case of multiple memories one initialization function per memory is needed. When the DPI is in the memory it is instead possible to scope.
For example see how we do this in one of my projects, where we add multiple memories in the cpp top: https://github.com/optimsoc/sources/blob/master/examples/sim/system_2x2_cccc/tb_system_2x2_cccc.cpp#L21 and then then the hierarchical names are used to scope into each of them for initialization: https://github.com/wallento/fusesoc_cores/blob/master/tools/simutil/verilator/src/VerilatedControl.cpp#L74
This seems a bit more elegant, but either would work just fine.
The next step here is to wait until AsyncReadMem
is ready and then move forward with:
AsyncReadMem
to read and write memory, and readmemh+loadmemhex
argument+loadmemelf
argument
This is the ELF, right?
Here is a recent discussion about it: https://groups.google.com/a/groups.riscv.org/forum/#!topic/sw-dev/NPYFXN4XNYk
There are two options:
loading the hex file via $readmemh and use DPI to trigger that function. Example: https://github.com/optimsoc/sources/blob/master/src/soc/hw/sram/verilog/sram_sp_impl_plain.sv#L116 and https://github.com/wallento/fusesoc_cores/blob/master/tools/simutil/verilator/src/VerilatedControl.cpp#L72 (a bit more complex)
using an ELF loader to load to memory. The memory array is accessed by a DPI function and the base address known. The ELF loaded is then loaded directly. For an example elf loader see https://github.com/openrisc/orpsoc-cores/blob/master/cores/elf-loader/elf-loader.c or https://github.com/opensocdebug/software/blob/master/src/memory.c#L337