Skip to content

Boring from a Probe with U-turn can cause illegal FIRRTL #5130

@seldridge

Description

@seldridge

Consider the following:

//> using repository https://central.sonatype.com/repository/maven-snapshots
//> using scala 2.13.18
//> using dep org.chipsalliance::chisel:7.5.0
//> using plugin org.chipsalliance:::chisel-plugin:7.5.0
//> using options -unchecked -deprecation -language:reflectiveCalls -feature -Xcheckinit
//> using options -Xfatal-warnings -Ywarn-dead-code -Ywarn-unused -Ymacro-annotations

import chisel3._
import chisel3.util.experimental.BoringUtils
import chisel3.probe.{Probe, ProbeValue, define}
import circt.stage.ChiselStage

class Baz extends RawModule {
}

class Bar extends RawModule {
  val a = IO(Output(Probe(Vec(2, Bool()), layers.Verification)))

  layer.block(layers.Verification) {
    val b = dontTouch(Wire(Vec(2, Bool())))
    b.foreach(_ :<= true.B)
    define(a, ProbeValue(b))
  }
}

class Qux(bar: Bar) extends RawModule {
  layer.block(layers.Verification) {
    val a = dontTouch(Wire(Vec(2, Bool())))
    a :<= BoringUtils.tapAndRead(bar.a)
  }
}

class Foo extends RawModule {
  private val bar = Module(new Bar)
  private val qux = Module(new Qux(bar))
}

object Main extends App {
  println(
    ChiselStage.emitCHIRRTL(
      new Foo
    )
  )
  println(
    ChiselStage.emitSystemVerilog(
      gen = new Foo,
      firtoolOpts = Array("--strip-debug-info", "--disable-layers=Verification.Assert,Verification.Assume,Verification.Cover")
    )
  )
}

When compiled, this produces:

Exception in thread "main" circt.stage.phases.Exceptions$FirtoolNonZeroExitCode: /Users/schuylereldridge/Library/Caches/org.chipsalliance.llvm-firtool/1.138.0/bin/firtool returned a non-zero exit code. Note that this version of Chisel (7.5.0) was published against firtool version 1.138.0.
------------------------------------------------------------------------------
ExitCode:
1
STDOUT:

STDERR:
/Users/schuylereldridge/repos/github.com/seldridge/scala-snippets/probes/BoringUtilsLayerColored.scala:29:33: error: 'firrtl.ref.resolve' op ambient layers are insufficient to resolve reference
    a :<= BoringUtils.tapAndRead(bar.a)
                                ^
/Users/schuylereldridge/repos/github.com/seldridge/scala-snippets/probes/BoringUtilsLayerColored.scala:29:33: note: see current operation: %2 = "firrtl.ref.resolve"(%0) : (!firrtl.probe<vector<uint<1>, 2>, @Verification>) -> !firrtl.vector<uint<1>, 2>
/Users/schuylereldridge/repos/github.com/seldridge/scala-snippets/probes/BoringUtilsLayerColored.scala:29:33: note: missing layer requirements: @Verification

The problem is that when BoringUtils creates the probes into Qux, it doesn't copy the layers along with it:

FIRRTL version 6.0.0
circuit Foo :%[[
  {
    "class":"firrtl.transforms.DontTouchAnnotation",
    "target":"~|Bar>b[0]"
  },
  {
    "class":"firrtl.transforms.DontTouchAnnotation",
    "target":"~|Bar>b[1]"
  },
  {
    "class":"firrtl.transforms.DontTouchAnnotation",
    "target":"~|Qux>a[0]"
  },
  {
    "class":"firrtl.transforms.DontTouchAnnotation",
    "target":"~|Qux>a[1]"
  }
]]
  layer Verification, bind, "verification" :
    layer Assert, bind, "verification/assert" :
      layer Temporal, inline :
    layer Assume, bind, "verification/assume" :
      layer Temporal, inline :
    layer Cover, bind, "verification/cover" :
      layer Temporal, inline :

  module Bar :
    output a : Probe<UInt<1>[2], Verification>

    skip
    layerblock Verification :
      wire b : UInt<1>[2]
      connect b[0], UInt<1>(0h1)
      connect b[1], UInt<1>(0h1)
      define a = probe(b)


  module Qux :
    input bore : UInt<1>[2]

    skip
    layerblock Verification :
      wire a : UInt<1>[2]
      connect a[0], bore[0]
      connect a[1], bore[1]


  public module Foo :

    inst bar of Bar
    inst qux of Qux
    connect qux.bore, read(bar.a)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions