Skip to content

Conversation

@debs-sifive
Copy link
Contributor

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)

Desired Merge Strategy

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

Release Notes

Create dontTouch.modulePorts method for marking all ports of a Module with DontTouchAnnotation.

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.6.x, 5.x, or 6.x depending on impact, API modification or big change: 7.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.

@debs-sifive debs-sifive added the Feature New feature, will be included in release notes label Feb 23, 2024
@seldridge
Copy link
Member

Is this necessary now that Public exists?

Copy link
Contributor

@jackkoenig jackkoenig left a comment

Choose a reason for hiding this comment

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

Generally LGTM, I don't love the name dontTouch.modulePorts but I also don't have a better idea so 🤷‍♀️

@seldridge @azidar do you have any opinions on the name? Also this API makes it such that it will dontTouch any ports added via BoringUtils even after the function is called (because the call to DataMirror.fullModulePorts is delayed

*
* @param module whose ports shouldl not get optimized away
*/
def modulePorts(module: BaseModule): BaseModule = {
Copy link
Contributor

Choose a reason for hiding this comment

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

You need an implicit SourceInfo here for DataMirror.fullModulePorts, that's why compilation is failing (incremental compile often hides this particular problem, that you can't materialize source locators in chisel core).

Comment on lines +57 to +59
def toFirrtl: Seq[Annotation] = (DataMirror.fullModulePorts(module).map {
case (_, data) => DontTouchAnnotation(data.toNamed)
})
Copy link
Contributor

Choose a reason for hiding this comment

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

fullModulePorts is returns every Aggregate and Element so this will result in dontTouching things multiple times. Can we instead maybe just use .modulePorts and call dontTouch.apply above (which does the recursion and only marks Elements)?

@jackkoenig
Copy link
Contributor

Is this necessary now that Public exists?

I agree with moving away from dontTouch generally but Public does impose additional constraints w.r.t. inferred resets and port widths that dontTouch doesn't.


/** Mark a module so that its ports will not get optimized away.
*
* @param module whose ports shouldl not get optimized away
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* @param module whose ports shouldl not get optimized away
* @param module whose ports should not get optimized away

data
}

/** Mark a module so that its ports will not get optimized away.
Copy link
Contributor

Choose a reason for hiding this comment

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

does this already do the right thing w.r.t. property ports and probe ports?

Copy link
Contributor

Choose a reason for hiding this comment

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

As we discussed in dev, we're fine to add this API but we should direct users to Public and Probe here in the API docs depending on the use case.

@seldridge
Copy link
Member

I agree with moving away from dontTouch generally but Public does impose additional constraints w.r.t. inferred resets and port widths that dontTouch doesn't.

Is not enforcing those constraints a requirement?

I'm trying to conserve concepts here and if this API is being used to create testable units, then I think those also probably want public and what it entails.

I won't hold this up as don't touch is a thing and having a utility to don't touch all the ports is generally useful. However, this is an intermediate API that I think we generally want to move off of.

@jackkoenig
Copy link
Contributor

jackkoenig commented Feb 23, 2024

I think there are 3 main historical use cases of this API:

  1. Give me these module ports "as is" in the Verilog -- as you noted this is just Public
  2. Give me the ports of this module such that I can access them with Verilog XMRs -- this can be handled with Probes and RWProbes
  3. I don't understand what is happening and want to debug, leave my ports alone so I can see them in the Verilog while I debug! -- I don't think we really have a great way to do this. Public sort of, but now the additional constraints are a problem when all you're trying to do is debug. Probes, again sort of, but you have to thread them to the top (BoringUtils helps but still extra boilerplate), and then of course read Probes intentionally do not block optimizations and RWProbes also are not really talking about keeping the ports themselves as much as keeping a forceable reference around.

(1) and (2) are what you should do in code that actually hits main, but (3) is still important IMO.

@seldridge
Copy link
Member

I think that makes sense. Is there anyway that we can prevent users using (3) in situations where they should be using (1) or (2)? Annoyingly, all I could think of is not providing this API. 🙃

}

"dontTouch.modulePorts" should "mark all ports of a module" in {
class ModuleWithPorts extends Module {
Copy link
Contributor

Choose a reason for hiding this comment

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

can we add a test for a Module with property and/or Probe ports? Im unclear if those are expected to be annotated, or there is supposed to be an error, or...?

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.

5 participants