chipsalliance / chipsalliance/chisel

ModuleChoice does not connect implicit clock/reset to FixedIOModule targets

Open
#5,383 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Scala
Stars
4.8k
Forks
658
Avg merge
18h 59m
Merged PRs (30d)
14

Description

**Type of issue**: Bug Report

**Please provide the steps to reproduce the problem:**
Run scala-cli on the following scala code (assisted by claude code sonnet 4.6).
```scala
//> using repository https://central.sonatype.com/repository/maven-snapshots
//> using scala 2.13.18
//> using dep org.chipsalliance::chisel:7.12.0+49-61358ac3-SNAPSHOT
//> using plugin org.chipsalliance:::chisel-plugin:7.12.0+49-61358ac3-SNAPSHOT
//> using options -unchecked -deprecation -language:reflectiveCalls -feature -Xcheckinit -Ymacro-annotations

import chisel3._
import chisel3.choice.{DynamicCase, DynamicGroup, ModuleChoice}
import _root_.circt.stage.ChiselStage

object MyGroup extends DynamicGroup("MyGroup") {
object Present extends DynamicCase
object NotPresent extends DynamicCase
}

// ---------------------------------------------------------------------------
// Case A: FixedIOModule — implicit clock/reset from Module
// ---------------------------------------------------------------------------

class SimpleIO extends Bundle {
val in = Input(UInt(8.W))
val out = Output(UInt(8.W))
}

class RegisteredFixedIOModule extends FixedIOModule[SimpleIO](new SimpleIO) {
val reg = RegInit(0.U(8.W))
reg := io.in
io.out := reg
}

class PassthroughFixedIOModule extends FixedIOModule[SimpleIO](new SimpleIO) {
io.out := io.in
}

// ModuleChoice with FixedIOModule — fails: "reset network never driven with concrete type"
class TopWithFixedIOModule extends Module {
val in = IO(Input(UInt(8.W)))
val out = IO(Output(UInt(8.W)))
val m = ModuleChoice(new RegisteredFixedIOModule)(Seq(
MyGroup.Present -> new RegisteredFixedIOModule,
MyGroup.NotPresent -> new PassthroughFixedIOModule,
))
m.in := in
out := m.out
}

// ---------------------------------------------------------------------------
// Case B: FixedIORawModule — explicit clock/reset in IO bundle (workaround)
// ---------------------------------------------------------------------------

class SimpleIOWithClockReset extends Bundle {
val clock = Input(Clock())
val reset = Input(Reset())
val in = Input(UInt(8.W))
val out = Output(UInt(8.W))
}

class RegisteredFixedIORawModule extends FixedIORawModule[SimpleIOWithClockReset](new SimpleIOWithClockReset) {
withClockAndReset(io.clock, io.reset) {
val reg = RegInit(0.U(8.W))
reg := io.in
io.out := reg
}
}

class PassthroughFixedIORawModule extends FixedIORawModule[SimpleIOWithClockReset](new SimpleIOWithClockReset) {
io.out := io.in
}

// ModuleChoice with FixedIORawModule — succeeds when clock/reset driven explicitly
class TopWithFixedIORawModule extends Module {
val in = IO(Input(UInt(8.W)))
val out = IO(Output(UInt(8.W)))
val m = ModuleChoice(new RegisteredFixedIORawModule)(Seq(
MyGroup.Present -> new RegisteredFixedIORawModule,
MyGroup.NotPresent -> new PassthroughFixedIORawModule,
))
m.clock := clock
m.reset := reset
m.in := in
out := m.out
}

// ---------------------------------------------------------------------------

object Main extends App {
println("=== Case B: FixedIORawModule (should succeed) ===")
println(ChiselStage.emitSystemVerilog(new TopWithFixedIORawModule))

println("=== Case A: FixedIOModule (should fail: reset network never driven with concrete type) ===")
println(ChiselStage.emitSystemVerilog(new TopWithFixedIOModule))
}

```

**What is the current behavior?**
firtool fails with:
```
error: reset network never driven with concrete type
val m = ModuleChoice(new RegisteredFixedIOModule)(Seq(
```
**What is the expected behavior?**

ModuleChoice should connect the enclosing module's implicit clock/reset to FixedIOModule targets, as `Module(new Foo)` does. I think implicit connection is missing for ModuleChoice(FixedIOModule)?

**Please tell us about your environment:**

**Other Information**

**What is the use case for changing the behavior?**

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.