Search code examples
chisel

Conditional Bulk Connection <>


I would like to do a conditional bulk connection of bidirectional buses, conceptually like the following.

val io = IO(new Bundle {
  val master = Decoupled(UInt(8.W))
  val slave0 = Flipped(Decoupled(UInt(8.W)))
  val slave1 = Flipped(Decoupled(UInt(8.W)))
  val select = Input(Bool())
})

when (select) {
  io.slave0 <> io.master
  io.slave1 <> some_null_decoupled
}.otherwise {
  io.slave1 <> io.master
  io.slave0 <> some_null_decoupled
}

This is cleaner than having to individually describe the logic for the io.master.ready, io.slave0.bits, io.slave0.valid, ... etc signals.

Is there a syntax similar to this which will work? When I try this in my code, I get a lot of firrtl.passes.CheckInitialization$RefNotInitializedException messages.


Solution

  • I suspect the issue is with the description of some_null_decoupled. That looks sane other than the fact that some_null_decoupled is missing. The following works fine for me (using Chisel 3.1.6):

    import chisel3._
    import chisel3.util._
    
    class ConditionalBulkConnect extends Module {
      val io = IO(new Bundle {
        val master = Decoupled(UInt(8.W))
        val slave0 = Flipped(Decoupled(UInt(8.W)))
        val slave1 = Flipped(Decoupled(UInt(8.W)))
        val select = Input(Bool())
      })
    
      val some_null_decoupled = Wire(Decoupled(UInt(8.W)))
      some_null_decoupled.ready := false.B
    
      when (io.select) {
        io.slave0 <> io.master
        io.slave1 <> some_null_decoupled
      }.otherwise {
        io.slave1 <> io.master
        io.slave0 <> some_null_decoupled
      }
    }
    
    object ConditionalBulkConnectTop extends App {
      chisel3.Driver.execute(args, () => new ConditionalBulkConnect)
    }
    

    Does this help at all? Otherwise can you provide more information, like the implementation of some_null_decoupled and version of Chisel?