chipsalliance / chipsalliance/chisel

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

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

Description

Consider the following:

``` scala
//> 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, 2>, @Verification>) -> !firrtl.vector, 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[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)
```

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.