Skip to content

ChiselSim cannot deal with 0-width signals and DontCare values #5230

@ccromjongh

Description

@ccromjongh

Type of issue: Bug Report (part Feature Request)

The currently available ChiseSim API does not deal well with DontCare values in vector and Bundle literals or with 0-width signals.

DontCare values are created in the literals where indexes/fields are unspecified. ChiselSim used to provide PokePartial that would only poke the provided indexes and not change the unspecified indexes.

Signals of 0-bit width may occur in parameterized designs. If the testing hardness is generic for the whole class that can be generated, it may try to poke a value to the 0-width signal, resulting in an error because the signal is pruned and hence does not exist in the simulation. ChiselTest includes a check for this, but ChiselSim does not.

Please provide the steps to reproduce the problem:

import chisel3._
import chisel3.experimental.BundleLiterals.AddBundleLiteralConstructor
import chisel3.experimental.VecLiterals.AddVecLiteralConstructor
import chisel3.simulator.scalatest.ChiselSim
import org.scalatest.funspec.AnyFunSpec

class BugReport extends AnyFunSpec with ChiselSim {

  class SomeBundle extends Bundle {
    val v1 = UInt(8.W)
    val v2 = Bool()
  }

  class Foo extends Module {
    val a = IO(Input(Vec(4, UInt(8.W))))
    val b = IO(Input(new SomeBundle))
    val c = IO(Input(UInt(0.W)))
    val d = IO(Output(chiselTypeOf(a)))

    private val r = RegNext(a)
    d := r
  }

  describe("Baz") {
    it("passes through vector literals") {
      simulate(new Foo) { foo =>
        // Raises java.util.NoSuchElementException: None.get
        foo.a.poke(chiselTypeOf(foo.a).Lit(0 -> 0.U, /*1 -> 2.U,*/ 2 -> 2.U, 3 -> 3.U))
        // Raises java.util.NoSuchElementException: None.get
        foo.b.poke(chiselTypeOf(foo.b).Lit(_.v1 -> 0.U/*, _.v2 -> true.B*/))
        foo.clock.step(1)
        // Raises chisel3.simulator.UninitializedElementException: Uninitialized Element
        // Vec element at index 1 in the expected value is not initialized
        foo.d.expect(chiselTypeOf(foo.a).Lit(0 -> 0.U, /*1 -> 2.U,*/ 2 -> 2.U, 3 -> 3.U))
        // Raises java.util.NoSuchElementException: key not found: Foo.c: IO[UInt<0>]
        foo.c.poke(0.U)
      }
    }
  }
}

What is the current behavior?
See the comments in the code above. Various exceptions are thrown

What is the expected behavior?
I think the minimum is receiving a more explicit error message relating to the actual problems. Of course, it would be better to insert checks into ChiselSim. I am not sure what the best solution is for the fields with DontCare. Providing PokePartial with the same behavior as ChiselTest is an option, or have it poke some specified or random value.

Please tell us about your environment:

  • version: 7.9
  • Verilator version: Verilator 5.044 2026-01-01 rev vUNKNOWN-built20260116-7e7b6d7
  • OS: Ubuntu 24.04.3 LTS on WSL2

Other Information

Based on my message on gitter.

What is the use case for changing the behavior?
Allowing for more flexible testing constructions without excessive condition checking by the user.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions