Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API for probing internal signals #3088

Merged
merged 37 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
1ab8b58
adding probes to ir/serializer
debs-sifive Mar 14, 2023
6b9aa53
scalafmt
debs-sifive Mar 14, 2023
4a4aa22
attempt to make spec example more sensical
debs-sifive Mar 15, 2023
c56375d
breaking up serializer test
debs-sifive Mar 16, 2023
b33198b
Merge branch 'main' into probes
azidar Mar 28, 2023
f1791fa
Merge branch 'chipsalliance:main' into probes
debs-sifive Apr 5, 2023
c64d9ae
first draft of user API
debs-sifive Apr 5, 2023
2161ae0
fixing probespec checks
debs-sifive Apr 5, 2023
df04b4f
adding test for connectors
debs-sifive Apr 5, 2023
75aeb23
pass of reviews
debs-sifive Apr 6, 2023
d6c3288
adding port binding check
debs-sifive Apr 7, 2023
e5ef2a5
moving probes out of experimental package
debs-sifive Apr 10, 2023
d8b6e0d
adding isProbe to DataMirror
debs-sifive Apr 10, 2023
5409404
fix refs
debs-sifive Apr 10, 2023
b43a759
fix probes with vecs
debs-sifive Apr 10, 2023
1bf49cb
adding scaladoc + stronger checks
debs-sifive Apr 10, 2023
3b327be
passiveness coercion for probes
debs-sifive Apr 10, 2023
44bea7e
clean up Data; add notes
debs-sifive Apr 13, 2023
1576292
change api to RW/Probe() and RW/ProbeValue() object
debs-sifive Apr 14, 2023
f82c6e7
Merge branch 'main' of github.com:chipsalliance/chisel3 into probes
debs-sifive Apr 17, 2023
f328002
fixing probe modifier checks for wire/reg/mem
debs-sifive Apr 17, 2023
d7ae759
added macros, make probe of probe illegal
debs-sifive Apr 17, 2023
51d599e
moving force/release methods into RWProbe only
debs-sifive Apr 17, 2023
a03531a
create probe package
debs-sifive Apr 17, 2023
522708e
fix converter merge
debs-sifive Apr 18, 2023
f590e1f
support accesses to probe subfields
debs-sifive Apr 21, 2023
1ba978f
test case for define type checking
debs-sifive Apr 21, 2023
733b5d9
forbid probe of aggregate containing probes
debs-sifive Apr 24, 2023
f4367af
fixing const extractType
debs-sifive Apr 24, 2023
0766aff
handling connections for probes
debs-sifive Apr 25, 2023
939d1bf
address schuyler's review
debs-sifive Apr 26, 2023
59f0ac3
additional tests and checks
debs-sifive Apr 26, 2023
957585b
add sourceInfo to Const
debs-sifive Apr 26, 2023
c4f0c60
fix probeInfoVar
debs-sifive Apr 26, 2023
92a4143
grouping macros for scaladoc
debs-sifive Apr 26, 2023
a9d5988
address jack's review
debs-sifive Apr 26, 2023
5f0031e
fix scaladoc groupings
debs-sifive Apr 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions firrtl/src/main/scala/firrtl/ir/IR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ abstract class Literal extends Expression {
val value: BigInt
val width: Width
}

case class ProbeExpr(expr: Expression) extends Expression with UseSerializer {
def tpe = ProbeType(expr.tpe)
}

case class ProbeRead(expr: Expression, tpe: Type = UnknownType) extends Expression with UseSerializer

case class UIntLiteral(value: BigInt, width: Width) extends Literal with UseSerializer {
def tpe = UIntType(width)
}
Expand Down Expand Up @@ -329,6 +336,17 @@ object Print {
}
}

case class ProbeDefine(info: Info, sink: Expression, probeExpr: Expression) extends Statement with UseSerializer

case class ProbeForceInitial(info: Info, probe: Expression, value: Expression) extends Statement with UseSerializer
case class ProbeReleaseInitial(info: Info, probe: Expression) extends Statement with UseSerializer
case class ProbeForce(info: Info, clock: Expression, cond: Expression, probe: Expression, value: Expression)
extends Statement
with UseSerializer
case class ProbeRelease(info: Info, clock: Expression, cond: Expression, probe: Expression)
extends Statement
with UseSerializer

// formal
object Formal extends Enumeration {
val Assert = Value("assert")
Expand Down Expand Up @@ -445,6 +463,9 @@ object GroundType {
def unapply(ground: GroundType): Option[Width] = Some(ground.width)
}
abstract class AggregateType extends Type

case class ProbeType(underlying: Type) extends Type with UseSerializer
case class RWProbeType(underlying: Type) extends Type with UseSerializer
case class UIntType(width: Width) extends GroundType with UseSerializer
case class SIntType(width: Width) extends GroundType with UseSerializer

Expand Down
16 changes: 15 additions & 1 deletion firrtl/src/main/scala/firrtl/ir/Serializer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ object Serializer {
case ValidIf(cond, value, _) => b ++= "validif("; s(cond); b ++= ", "; s(value); b += ')'
case SIntLiteral(value, width) =>
b ++= "SInt"; s(width); b ++= "(\"h"; b ++= value.toString(16); b ++= "\")"
case other => b ++= other.serialize // Handle user-defined nodes
case ProbeExpr(expr) => b ++= "probe("; s(expr); b += ')'
case ProbeRead(expr, _) => b ++= "read("; s(expr); b += ')'
case other => b ++= other.serialize // Handle user-defined nodes
}

// Helper for some not-real Statements that only exist for Serialization
Expand Down Expand Up @@ -278,6 +280,16 @@ object Serializer {
case firrtl.CDefMPort(info, name, _, mem, exps, direction) =>
b ++= direction.serialize; b ++= " mport "; b ++= name; b ++= " = "; b ++= mem
b += '['; s(exps.head); b ++= "], "; s(exps(1)); s(info)
case ProbeDefine(info, sink, probeExpr) =>
b ++= "define "; s(sink); b ++= " = "; s(probeExpr); s(info)
case ProbeForceInitial(info, probe, value) =>
b ++= "force_initial("; s(probe); b ++= ", "; s(value); b += ')'; s(info)
case ProbeReleaseInitial(info, probe) =>
b ++= "release_initial("; s(probe); b += ')'; s(info)
case ProbeForce(info, clock, cond, probe, value) =>
b ++= "force("; s(clock); b ++= ", "; s(cond); b ++= ", "; s(probe); b ++= ", "; s(value); b += ')'; s(info)
case ProbeRelease(info, clock, cond, probe) =>
b ++= "release("; s(clock); b ++= ", "; s(cond); b ++= ", "; s(probe); b += ')'; s(info)
case other => b ++= other.serialize // Handle user-defined nodes
}

Expand Down Expand Up @@ -309,6 +321,8 @@ object Serializer {

private def s(node: Type)(implicit b: StringBuilder, indent: Int): Unit = node match {
// Types
case ProbeType(underlying: Type) => b ++= "Probe<"; s(underlying); b += '>'
case RWProbeType(underlying: Type) => b ++= "RWProbe<"; s(underlying); b += '>'
case UIntType(width: Width) => b ++= "UInt"; s(width)
case SIntType(width: Width) => b ++= "SInt"; s(width)
case BundleType(fields) => b ++= "{ "; sField(fields, ", "); b += '}'
Expand Down
65 changes: 65 additions & 0 deletions firrtl/src/test/scala/firrtlTests/SerializerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,50 @@ object SerializerSpec {
"test"
)

val probeModule: String =
"""module probeModule :
| input clock : Clock
| input cond : UInt<1>
| input in : UInt<8>
| input inProbe : Probe<UInt<8>>
| output out : UInt<8>

| inst c of child
| wire fooProbe : Probe<UInt<8>>
| c.in <= in
| define fooProbe = probe(c.in)
| out <= read(out)
| force_initial(inProbe, UInt<8>("h64"))
| release_initial(inProbe)
| force(clock, cond, inProbe, in)
| release(clock, cond, inProbe)""".stripMargin

val probeModuleIR: Module =
Module(
NoInfo,
"probeModule",
Seq(
Port(NoInfo, "clock", Input, ClockType),
Port(NoInfo, "cond", Input, UIntType(IntWidth(1))),
Port(NoInfo, "in", Input, UIntType(IntWidth(8))),
Port(NoInfo, "inProbe", Input, ProbeType(UIntType(IntWidth(8)))),
Port(NoInfo, "out", Output, UIntType(IntWidth(8)))
),
Block(
Seq(
DefInstance("c", "child"),
DefWire(NoInfo, "fooProbe", ProbeType(UIntType(IntWidth(8)))),
Connect(NoInfo, SubField(Reference("c"), "in"), Reference("in")),
ProbeDefine(NoInfo, Reference("fooProbe"), ProbeExpr(SubField(Reference("c"), "in"))),
Connect(NoInfo, Reference("out"), ProbeRead(Reference("out"))),
ProbeForceInitial(NoInfo, Reference("inProbe"), UIntLiteral(100, IntWidth(8))),
ProbeReleaseInitial(NoInfo, Reference("inProbe")),
ProbeForce(NoInfo, Reference("clock"), Reference("cond"), Reference("inProbe"), Reference("in")),
ProbeRelease(NoInfo, Reference("clock"), Reference("cond"), Reference("inProbe"))
)
)
)

}

/** used to test parsing and serialization of smems */
Expand Down Expand Up @@ -176,4 +220,25 @@ class SerializerSpec extends AnyFlatSpec with Matchers {
SMemTestCircuit.circuit(ReadUnderWrite.New).serialize should include("new")
SMemTestCircuit.circuit(ReadUnderWrite.Old).serialize should include("old")
}

it should "support emitting Probe/RWProbe types and related expressions/statements" in {
val probeInt = DefWire(NoInfo, "foo", ProbeType(UIntType(IntWidth(3))))
Serializer.serialize(probeInt) should be("wire foo : Probe<UInt<3>>")

val rwProbeBundle = DefWire(
NoInfo,
"foo",
RWProbeType(
BundleType(
Seq(
Field("bar", Default, UIntType(IntWidth(32)))
)
)
)
)
Serializer.serialize(rwProbeBundle) should be("wire foo : RWProbe<{ bar : UInt<32>}>")

// check probe expressions and statements
Serializer.serialize(probeModuleIR) should be(probeModule)
}
}