I'm writing a SPI to Wishbone component with Chisel3, and for testing it on FPGA/real world I have to change the polarity of the reset (rstn).
To manage it I used RawModule
for my Top module. And I used withClockAndReset()
to change the reset polarity :
class TopSpi2Wb extends RawModule {
val clock = IO(Input(Clock()))
val rstn = IO(Input(Bool()))
// ...
withClockAndReset(clock, !rstn) {
val spi2Wb = Module(new Spi2Wb(dwidth, awidth))
// module connections IO
}
It seem's to works since I tryied to instanciate a Sync memory on the wishbone port. with this kind of code:
class TopSpi2Wb extends RawModule {
val clock = IO(Input(Clock()))
val rstn = IO(Input(Bool()))
// ...
withClockAndReset(clock, !rstn) {
val spi2Wb = Module(new Spi2Wb(dwidth, awidth))
val wmem = SyncReadMem(1 << awidth, UInt(dwidth.W))
val ackReg = RegInit(false.B)
val datReg = RegInit(0.U(dwidth.W))
ackReg := false.B
datReg := 0.U(dwidth.W)
when(spi2Wb.io.wbm.stb_o && spi2Wb.io.wbm.cyc_o) {
when(spi2Wb.io.wbm.we_o){
wmem.write(spi2Wb.io.wbm.adr_o, spi2Wb.io.wbm.dat_o)
datReg := DontCare
}.otherwise{
datReg := wmem.read(spi2Wb.io.wbm.adr_o, spi2Wb.io.wbm.stb_o &
spi2Wb.io.wbm.cyc_o & !spi2Wb.io.wbm.we_o)
}
// ...
That compile without error, but I can't manage to read/write on memory correctly (with icarus). Verilog emitted seems to drop memory instantiation.
Maybe it's discouraged to write chisel code like Register, memories, ... and just instantiate one top module in RawModule no ?
Well, if I'm wrapping a top module in the RawModule, that works really better:
// Testing Spi2Wb with a memory connexion
// and reset inverted
class TopSpi2Wb extends RawModule {
// Clock & Reset
val clock = IO(Input(Clock()))
val rstn = IO(Input(Bool()))
// Simple blink
val blink = IO(Output(Bool()))
// SPI
val mosi = IO(Input(Bool()))
val miso = IO(Output(Bool()))
val sclk = IO(Input(Bool()))
val csn = IO(Input(Bool()))
val dwidth = 8
val awidth = 7
withClockAndReset(clock, !rstn) {
val spi2Wb = Module(new Spi2WbMem(dwidth, awidth))
blink := spi2Wb.io.blink
spi2Wb.io.mosi := mosi
miso := spi2Wb.io.miso
spi2Wb.io.sclk := sclk
spi2Wb.io.csn := csn
}
}
With the code above, all connection and register instantiation for Wishbone memory are done in Spi2WbMem()
standard module.
As jkoenig asked I re-written the module to reproduce the bug and ... fixed it ! Sorry for the inconvenience.
I had some difficulties to find the bug because Icarus didn't dump the content of memory and I thought it was not generated.
I think that my initial module wrapping fixed the bug without my realizing it.