Vec of Bundle как параметр модуля - PullRequest
1 голос
/ 11 октября 2019

Я пишу Wishbone Intercon модуль для автоматического декодирования адреса. У меня есть два класса Bundle, которые описывают интерфейс Wishbone master и Wishbone slave.

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(?)
    })
}

Цель состоит в том, чтобы разрешить переменное число ведомых рычагов и позволить модулю выполнятьсантехника. Например:

  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))

Вопрос несколько:

  • это правильный способ сделать это?
  • Как объявить Vec () в модулепараметры?

Я пробовал это, но не работает:

// 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())}
    })
}

Ответы [ 2 ]

1 голос
/ 12 октября 2019

I нашел решение с помощью MixedVec (экспериментальный) модуль. Я просто передал Seq WbSlave Bundle в качестве параметра модуля и сделал 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
    }
}

Это компилируется в testbench .

1 голос
/ 11 октября 2019

Попробуйте думать о своих параметрах как о генераторах нужных вам типов. Ниже приведен игрушечный пример этой идеи. В этом случае один параметр конструктора bgen - это метод генератора, который будет возвращать экземпляр 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))
  }
}
...