Bundle 的 Vec 作为 Module 参数

Vec of Bundle as a Module parameter

我正在编写一个 Wishbone Intercon 模块来自动进行地址解码。 我有两个描述 Wishbone master 和 Wishbone slave 接口的 Bundle 类。

class WbMaster (val dwidth: Int,
                val awidth: Int) extends Bundle {
    val adr_o = Output(UInt(awidth.W))
//...
    val cyc_o = Output(Bool())
}

// Wishbone slave interface
class WbSlave (val dwidth: Int,
               val awidth: Int) extends Bundle {
  val adr_i = Input(UInt(awidth.W))
//...
  val cyc_i = Input(Bool())
}

我想将这些 Bundle 作为参数传递给我的模块 Wishbone,如下所示:

class WbInterconOneMaster(val awbm: WbMaster,
                          val awbs: Vec(WbSlave)) extends Module {
    val io = IO(new Bundle{
      val wbm = Flipped(new WbMaster(awbm.dwidth, awbm.awidth))
      val wbs = Vec(?)
    })
}

objective 是允许可变数量的叉骨奴隶,让模块做管道。喜欢以下内容:

  val spi2Wb = Module(new Spi2Wb(dwidth, awidth))
  val wbMdio1 = Module(new MdioWb(mainFreq, targetFreq))
  val wbMdio2 = Module(new MdioWb(mainFreq, targetFreq))

  val slavesVec = Vec(Seq(wbMdio1, wbMdio2))

  val wbIntercon = Module(new WbIntercon(spi2Wb.io.wbm, slavesVec))

问题是多个:

我试过这个但没有用:

// Wishbone Intercone with one master and several slaves
// data bus is same size as master
class WbInterconOneMaster(val awbm: WbMaster,
                          val awbs: Vec[Seq[WbSlave]]) extends Module {
    val io = IO(new Bundle{
      val wbm = Flipped(new WbMaster(awbm.dwidth, awbm.awidth))
      val wbs = Vec.fill(awbs.size){awbs.map(_.cloneType())}
    })
}

尝试将参数视为所需类型的生成器。以下是这个想法的玩具示例。在这种情况下,一个构造函数参数 bgen 是一个生成器方法,它将 return Bundle 的一个实例。它显示了此生成器的原样使用以及作为 Vec

的一部分的使用
class BundleX extends Bundle {
  val a = UInt(8.W)
  val b = UInt(8.W)
}

class ModuleX(bgen: () => BundleX, numInputs: Int) extends Module {
  val io = IO(new Bundle{
    val in1  = Input(Vec(numInputs, bgen()))
    val out1 = Output(bgen())
  })
  // output fields a and b are the the sum of all the corresponding inputs
  io.out1.a := io.in1.foldLeft(0.U) { case (res, value) => res +% value.a}
  io.out1.b := io.in1.foldLeft(0.U) { case (res, value) => res +% value.b}
}

class BundleXSpec extends ChiselPropSpec {
  property("testname") {
    elaborate(new ModuleX(() => new BundleX, 4))
  }
}

found a solution 使用 MixedVec(实验)模块。我只是将一个 WbSlave Bundle 的 Seq 作为模块参数传递,然后我制作了一个 MixedVec(WbSlave 实际上可以有不同的参数):

class WbInterconOneMaster(val awbm: WbMaster,
                          val awbs: Seq[WbSlave]) extends Module {
    val io = IO(new Bundle{
      val wbm = Flipped(new WbMaster(awbm.dwidth, awbm.awidth))
      val wbs = MixedVec(awbs.map{i => new WbSlave(i.dwidth, i.awidth)})
    })

    io.wbm.dat_i := 0.U
    io.wbm.ack_i := 0.U
    for(i <- 0 until io.wbs.size){
      io.wbs(i).dat_o := 0.U
      io.wbs(i).ack_o := 0.U
    }
}

the testbench中编译。