【发布时间】:2019-09-17 08:54:47
【问题描述】:
我正在写一个SPI to Wishbone component with Chisel3,为了在 FPGA/现实世界上测试它,我必须改变复位的极性 (rstn)。
为了管理它,我使用RawModule 作为我的顶级模块。我用withClockAndReset() 改变了复位极性:
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
}
自从我尝试在叉骨端口上实例化同步内存后,它似乎可以工作了。使用这种代码:
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)
}
// ...
编译没有错误,但我无法正确读取/写入内存(使用 icarus)。发出的 Verilog 似乎放弃了内存实例化。
也许不鼓励编写 凿子代码,例如 Register、memory 等,而只在 RawModule 中实例化 一个 顶级模块?
好吧,如果我在 RawModule 中包装一个 top 模块,效果会更好:
// 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
}
}
使用上面的代码,Wishbone 内存的所有连接和寄存器实例化都在Spi2WbMem() 标准 模块中完成。
【问题讨论】:
-
访问你的仓库非常有用,但我很难重复这个错误。也许你可以在你的 repo 中创建一个分支来专门展示这个错误。
-
在 RawModule 中放入尽可能多的逻辑和状态并没有错。就像一个愚蠢的健全性检查一样,你有内存用于驱动的输出,对吗?否则它可能会被 DeadCodeElimination 删除。如果不是那么简单,一个可运行的示例将有助于调试。