chisel icon indicating copy to clipboard operation
chisel copied to clipboard

Confusing bundle connection behavior with SRAM API

Open tymcauley opened this issue 4 months ago • 0 comments

Type of issue: Bug Report

Please provide the steps to reproduce the problem:

The scala-cli snippet below gives a few different errors that you can cause:

  • Set readerUnintError to true
  • Set writerUnintError to true
  • Comment out the existing myMem.writePorts connection, and use one of the other commented-out options
//> using scala 2.13.16
//> using repository https://s01.oss.sonatype.org/content/repositories/snapshots
//> using dep org.chipsalliance::chisel:7.0.0-RC1+28-2f256a83-SNAPSHOT
//> using plugin org.chipsalliance:::chisel-plugin:7.0.0-RC1+28-2f256a83-SNAPSHOT
//> using options -unchecked -deprecation -language:reflectiveCalls -feature -Xcheckinit -Xfatal-warnings -Ywarn-dead-code -Ywarn-unused -Ymacro-annotations

import chisel3._
import chisel3.util._

class Reader(readPort: MemoryReadPort[UInt], uninitError: Boolean = false) extends Module {
  // `Flipped` because default `MemoryReadPort` alignment is `Input`
  val port = IO(Flipped(readPort))

  if (uninitError) {
    port :<= DontCare
  } else {
    port.address :<= DontCare
    port.enable :<= DontCare
  }
}

class Writer(writePort: MemoryWritePort[UInt], uninitError: Boolean = false) extends Module {
  // `Flipped` because default `MemoryWritePort` alignment is `Input`
  val port = IO(Flipped(writePort))

  if (uninitError) {
    port :<= DontCare
  } else {
    port.address :<= DontCare
    port.data :<= DontCare
    port.enable :<= DontCare
  }
}

class Foo extends Module {
  val myMem = SRAM(8, UInt(5.W), 1, 1, 0)

  val readPort = chiselTypeOf(myMem.readPorts.head)
  val writePort = chiselTypeOf(myMem.writePorts.head)

  // If set to `true`, firtool error: sink * not fully initialized in "Reader"
  val readerUnintError = false

  // If set to `true`, firtool error: sink * not fully initialized in "Writer"
  val writerUnintError = false

  val reader = Module(new Reader(readPort, readerUnintError))
  val writer = Module(new Writer(writePort, writerUnintError))

  // This works
  reader.port :<>= myMem.readPorts.head

  // firtool error: sink * not fully initialized in "Foo"
  // myMem.writePorts.head :<= writer.port

  // Chisel error: port.* in Writer cannot be written from module Foo.
  // myMem.writePorts.head :<>= writer.port

  // This works, but the LHS-vs-RHS isn't intuitive.
  // writer.port :>= myMem.writePorts.head

  // This works, has the LHS-vs-RHS I would expect, but is inconvenient due to enumerating each bundle element
  myMem.writePorts.head.address :<= writer.port.address
  myMem.writePorts.head.data :<= writer.port.data
  myMem.writePorts.head.enable :<= writer.port.enable
}

object Main extends App {
  import _root_.circt.stage.ChiselStage
  println(
    ChiselStage.emitSystemVerilog(
      new Foo,
      firtoolOpts = Array("-disable-all-randomization", "-strip-debug-info", "-default-layer-specialization=enable")
    )
  )
}

What is the current behavior?

I'm unable to make connections to the Memory*Port bundles that I would expect, perhaps due to their default alignment being Input rather than Output: https://github.com/chipsalliance/chisel/blob/2f256a835c4f02f53b62f9026f66355216cd6a85/src/main/scala-2/chisel3/util/SRAM.scala#L23-L82

Rather than being able to make connections like port :<= DontCare, I either need to break out the fields of port and connect to them individually (port.address :<= DontCare; port.enable :<= DontCare; ...), or I need to use an unintuitive LHS-vs-RHS style: DontCare :>= port. Is this the intended behavior, or is this just an annoying edge case in the Connectable (or SRAM) API?

What is the expected behavior?

I should be able to connect bundles with matching alignment, and put the producer and consumer on the sides of the Connectable operator that I would expect.

Please tell us about your environment: - version: 7.0.0-RC1+28-2f256a83-SNAPSHOT - OS: macOS 15.5

Other Information

What is the use case for changing the behavior?

Making the Connectable API more convenient for users.

tymcauley avatar Jun 02 '25 20:06 tymcauley