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

Support probe-define in monoconnects #3566

Merged
merged 14 commits into from Oct 17, 2023
Merged

Conversation

rwy7
Copy link
Contributor

@rwy7 rwy7 commented Oct 3, 2023

  • Enable mono/ :=connects for probes, which will emit a ProbeDefine.
  • Also enables the fancier connect forms
  • A "Probe" will be connected at the root

Co-authored-by: Will Dietz will.dietz@sifive.com

Contributor Checklist

  • Did you add Scaladoc to every public function/method?
  • Did you add at least one test demonstrating the PR?
  • Did you delete any extraneous printlns/debugging code?
  • Did you specify the type of improvement?
  • Did you add appropriate documentation in docs/src?
  • Did you request a desired merge strategy?
  • Did you add text to be included in the Release Notes for this change?

Type of Improvement

  • Feature (or new API)
  • API modification

Desired Merge Strategy

  • Squash: The PR will be squashed and merged (choose this if you have no preference).

Release Notes

  • Enable mono/ :=connects for probes, which will emit a ProbeDefine.
  • Also enables the fancier connect forms
  • A "Probe" will be connected at the root

Reviewer Checklist (only modified by reviewer)

  • Did you add the appropriate labels? (Select the most appropriate one based on the "Type of Improvement")
  • Did you mark the proper milestone (Bug fix: 3.5.x, 3.6.x, or 5.x depending on impact, API modification or big change: 6.0)?
  • Did you review?
  • Did you check whether all relevant Contributor checkboxes have been checked?
  • Did you do one of the following when ready to merge:
    • Squash: You/ the contributor Enable auto-merge (squash), clean up the commit message, and label with Please Merge.
    • Merge: Ensure that contributor has cleaned up their commit history, then merge with Create a merge commit.

@rwy7 rwy7 marked this pull request as ready for review October 4, 2023 13:56
@seldridge seldridge added the Feature New feature, will be included in release notes label Oct 4, 2023
Comment on lines -246 to 254
case a: Record =>
case a: Record if (!hasProbeTypeModifier(a)) =>
a._elements.iterator.flatMap {
case (fieldName, fieldData) =>
collectMembersAndPaths(fieldData, s"$path.$fieldName")(collector)
}
case a: Vec[_] =>
case a: Vec[_] if (!hasProbeTypeModifier(a)) =>
a.elementsIterator.zipWithIndex.flatMap {
case (fieldData, fieldIndex) =>
collectMembersAndPaths(fieldData, s"$path($fieldIndex)")(collector)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these here? It seems to me that DataMirror should return probes as well and perhaps the onus is on the user providing a collector function that excludes probes if that is the behavior they want?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stops it from recursing /through/ probes, not excluding them, FWIW.

The collector you're describing is used in, e.g., excludeProbes, but the idea here is that Probes are opaque in the sense that's being iterated over here -- they're basically Element in that sense, with an underlying probed type that itself may have children but the probe itself does not.

As-is no collector definition (AFAIK?) can use this (pre-this-PR) to provide the useful behavior of treating probes as the leaves of aggregates that they are.

All that said, what this method is """supposed""" to do independent of our immediate needs I can't speak for (such as it's expected to recurse in same way other things do), so if it's not directly needed sure we can drop it, if that seems better!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stops it from recursing /through/ probes, not excluding them, FWIW.

Good point, thanks for pointing that out

The collector you're describing is used in, e.g., excludeProbes, but the idea here is that Probes are opaque in the sense that's being iterated over here -- they're basically Element in that sense, with an underlying probed type that itself may have children but the probe itself does not.

As-is no collector definition (AFAIK?) can use this (pre-this-PR) to provide the useful behavior of treating probes as the leaves of aggregates that they are.

This is a fair point, but I think it highlights a much larger issue (and one that we do currently run into with OpaqueTypes as well) that we don't really have a way to talk about "leaves" other than Element. I think the change you're getting at here makes a lot of sense, but I think it necessitates coming up with the new API for "leaf".

All that said, what this method is """supposed""" to do independent of our immediate needs I can't speak for (such as it's expected to recurse in same way other things do), so if it's not directly needed sure we can drop it, if that seems better!

You've convinced me that this is the right thing to do for this PR. We probably need to prioritize finding a better way to discuss leaves though.

I want to note that collectLeafMembers above is probably broken as it is expressed as:

  def collectLeafMembers(d: Data): Seq[Data] =
    DataMirror.collectMembers(d) { case x: Element => x }.toVector

It will ignore Aggregate probes even though those are leaves. It's also extremely likely that anyone calling that method is immediately matching on Element though....

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯 , agreed and interesting/good to know about OpaqueType. Hopefully soon we can get into business of working on these things and making everything awesome 🚀 .

Good catch re:collectLeafMembers, thank you for looking / thinking about that!! I think you're right.

@@ -184,20 +184,21 @@ private[chisel3] object Connection {
// Recursive Case 4: non-empty orientations
case (conAlign: NonEmptyAlignment, proAlign: NonEmptyAlignment) =>
(conAlign.member, proAlign.member) match {
case (consumer: Aggregate, producer: Aggregate) =>
case (consumer: Aggregate, producer: Aggregate)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be great to make Probes their own type (since they are), but for now these guards help treat probes in this way.

})
io.out :<>= io.in
},
Array("--throw-on-first-error")
)
}
exc.getMessage should include("Cannot use connectables with probe types. Exclude them prior to connection.")
exc.getMessage should include(
"mismatched probe/non-probe types in ProbeSpec_Anon.io.out[0]: IO[Bool] and ProbeSpec_Anon.io.in[0]: IO[Bool]."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Pre-existing issue/opportunity for improvement: Probe's aren't printed accurately, printed ignoring their probe-ness)

Comment on lines -246 to 254
case a: Record =>
case a: Record if (!hasProbeTypeModifier(a)) =>
a._elements.iterator.flatMap {
case (fieldName, fieldData) =>
collectMembersAndPaths(fieldData, s"$path.$fieldName")(collector)
}
case a: Vec[_] =>
case a: Vec[_] if (!hasProbeTypeModifier(a)) =>
a.elementsIterator.zipWithIndex.flatMap {
case (fieldData, fieldIndex) =>
collectMembersAndPaths(fieldData, s"$path($fieldIndex)")(collector)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stops it from recursing /through/ probes, not excluding them, FWIW.

The collector you're describing is used in, e.g., excludeProbes, but the idea here is that Probes are opaque in the sense that's being iterated over here -- they're basically Element in that sense, with an underlying probed type that itself may have children but the probe itself does not.

As-is no collector definition (AFAIK?) can use this (pre-this-PR) to provide the useful behavior of treating probes as the leaves of aggregates that they are.

All that said, what this method is """supposed""" to do independent of our immediate needs I can't speak for (such as it's expected to recurse in same way other things do), so if it's not directly needed sure we can drop it, if that seems better!

Copy link
Contributor

@mwachs5 mwachs5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should add some words to this to explain how probe-ness has to match too: https://github.com/chipsalliance/chisel/blob/main/docs/src/explanations/connectable.md#terminology

In the "structural type check" bullet are we now saying that "structural type check" includes 'probe-ness', or "alignment type check" includes 'probe-ness', or should "probe-ness type check" be its own bullet

@@ -43,7 +43,7 @@ section: "chisel3"
* E.g. `IO(Decoupled(Bool)).ready` is a member of the parent `IO` component
* "relative alignment" - whether two members of the same component or Chisel type are aligned/flipped, relative to one another
* see section [below](#alignment-flipped-vs-aligned) for a detailed definition
* "structural type check" - Chisel type `A` is structurally equivalent to Chisel type `B` if `A` and `B` have matching bundle field names and types (`Record` vs `Vector` vs `Element`), vector sizes, `Element` types (UInt/SInt/Bool/Clock etc))
* "structural type check" - Chisel type `A` is structurally equivalent to Chisel type `B` if `A` and `B` have matching bundle field names and types (`Record` vs `Vector` vs `Element`), probe modifiers (probe vs nonprobe), vector sizes, `Element` types (UInt/SInt/Bool/Clock)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I've snuck in a bit that says, A and B should have matching probe modifiers.

Copy link
Member

@dtzSiFive dtzSiFive left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@dtzSiFive
Copy link
Member

(6.0 milestone sound right?)

@jackkoenig
Copy link
Contributor

(6.0 milestone sound right?)

Yep, Probes are new in Chisel 6

@jackkoenig jackkoenig merged commit 54fbf40 into chipsalliance:main Oct 17, 2023
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature New feature, will be included in release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants