Optional Module I/O

16 views
Skip to first unread message

Brendon Chetwynd

unread,
Jun 3, 2024, 7:36:19 AMJun 3
to Chipyard
In the chipyard example, GCD.scala, the underlying module implementation is selected based on a `useBlackBox` parameter.  The I/O for this module is then passed to `val impl_io` for connection to signals within GCDTL.

One challenge I am facings is `what if my IO definitions for my underlying modules were different?`.

In my code, one version of my IO has six additional signals.  While I know my conditional module instantiation is correct (again, borrowed from GCD.scala), errors occur when performing the connections in the higher level modules.

Some example code to make the point:

Module A:

 class moduleA() extends BlackBox with HasBlackBoxResource {

    val io = IO(new Bundle {
      // Clock and Reset
      val clk                 = Input(Clock())
      val rst                 = Input(Reset())

      // Inputs
      val start               = Input(Bool())
      val valid             = Output(Bool())

  })
}

Module B:

 class moduleB() extends BlackBox with HasBlackBoxResource {

    val io = IO(new Bundle {
      // Clock and Reset
      val clk                 = Input(Clock())
      val rst                 = Input(Reset())

      // Inputs
      val start               = Input(Bool())
  })
}

  val myModule_io = if (useModuleA) {
    val impl  = Module(new 
moduleA  ())
    impl.io
  } else {
    val impl  = Module(new 
moduleB ())
    impl.io
  }


Connections:
if (useModuleA) {
     myModule_io  .clk                 := clock
     myModule_io  .rst                 := reset
     myModule_io.start               := start
     valid                                             := myModule_io.valid
} else {
      myModule_io  .clk                 := clock
     myModule_io  .rst                 := reset
     myModule_io.start               := start
}

During compilation, it will complains that valid is not a member of myModule_io, despite being sure that useModuleA is defined.


Jerry Zhao

unread,
Jun 3, 2024, 1:43:39 PMJun 3
to chip...@googlegroups.com
Try:

  val io = IO(new ModuleAIO)

And:

  myModule_io.asInstanceOf[ModuleAIO].xxx := yyy

-Jerry



--
You received this message because you are subscribed to the Google Groups "Chipyard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chipyard+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/chipyard/2c3e7f94-dc53-46d8-99bb-ae0de220ab37n%40googlegroups.com.

Hasan Genc

unread,
Jun 4, 2024, 9:04:31 PMJun 4
to chip...@googlegroups.com
Your issue is that the example code you gave won’t even compile (let alone elaborate), right? If so, the easiest workaround would be to use Scala’s “Either” class when defining “myModule_io” like this:

  val myModule_io = if (useModuleA) {
    val impl  = Module(new 
 moduleA  
())
    Left(impl.io)

  } else {
    val impl  = Module(new 
 moduleB ())
    Right(impl.io)
  }


Connections:
myModule_io match {
    case Left(moduleA_io) =>
        moduleA_io.clk := clock
        moduleA_io.rst := reset
        moduleA_io.start := start
        valid := moduleA_io.valid
    case Right(moduleB_io) =>
        moduleB_io.clk := clock
        moduleB_io.rst := reset
        moduleB_io.start := start
}

Regards,
Hasan

On Mon, Jun 3, 2024 at 4:36 AM Brendon Chetwynd <bche...@gmail.com> wrote:
Reply all
Reply to author
Forward
0 new messages