Skip to content

Conversation

fabianschuiki
Copy link
Contributor

Add support for CIRCT's circt_verif_require and circt_verif_ensure intrinsics. These interact with the formal contracts implemented in CIRCT and translate to asserts or assumes depending on whether the contract is checked or applied. They lower to asserts if used outside of a contract.

Chisel itself has no support for contracts yet, such that these two additions behave like AssertProperty in practice. As soon as contracts are added to Chisel though, they can be used to formulate the pre- and post-conditions of those contracts.

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

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) and clean up the commit message.
    • Merge: Ensure that contributor has cleaned up their commit history, then merge with Create a merge commit.

@fabianschuiki fabianschuiki added the Feature New feature, will be included in release notes label Feb 12, 2025
Comment on lines 508 to 520
/** Require that a property holds as a pre-condition of a contract. Behaves like
* an `AssertProperty` if used outside of a contract.
*
* Use like `RequireProperty(p)`. See `AssertPropertyLike.apply` for optional
* clock, disable_iff, and label parameters.
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

This applies to all ScalaDoc so perhaps better left to a follow on docs update, but There's no need to look at AssertPropertyLike.apply, all apply methods are inherited and thus available on all of these objects.

Also rather than "Use like" we should just put a ScalaDoc example.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. I can do a pass over the LTL stuff in a follow-up PR to clean the docs up in one go. An example for each would be nice 👍

*/
object EnsureProperty extends AssertPropertyLike(defaultLayer = layers.Verification.Assert) {
protected def createIntrinsic(label: Option[String])(implicit sourceInfo: SourceInfo) = VerifEnsureIntrinsic(label)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

New APIs need to be added to src/main/scala-3 as well or we are just creating more work for ourselves in the future.

Copy link
Contributor Author

@fabianschuiki fabianschuiki Feb 20, 2025

Choose a reason for hiding this comment

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

None of this currently exists in src/main/scala-3. It's going to be easier to do this separately in one go, instead of turning a PR adding a few APIs into a PR that does Scala 3 migration plus adding a few APIs.

* Use like `EnsureProperty(p)`. See `AssertPropertyLike.apply` for optional
* clock, disable_iff, and label parameters.
*/
object EnsureProperty extends AssertPropertyLike(defaultLayer = layers.Verification.Assert) {
Copy link
Contributor

Choose a reason for hiding this comment

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

How does AssumeProperty differ from AssertProperty and how does EnsureProperty differ from AssertProperty when used in a formal contract?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They are interpreted as assume or assert depending on whether the contract itself is checked, or whether it is assumed to hold to simplify parent proofs. I've added a few more sentences to roughly explain what happens.

Add support for CIRCT's `circt_verif_require` and `circt_verif_ensure`
intrinsics. These interact with the formal contracts implemented in
CIRCT and translate to asserts or assumes depending on whether the
contract is checked or applied. They lower to asserts if used outside of
a contract.

Chisel itself has no support for contracts yet, such that these two
additions behave like `AssertProperty` in practice. As soon as contracts
are added to Chisel though, they can be used to formulate the pre- and
post-conditions of those contracts.
Copy link
Member

@seldridge seldridge left a comment

Choose a reason for hiding this comment

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

LGTM

@jackkoenig: The marginal cost of migrating this patch to Scala 3 on top of the cost of migrating the whole file to Scala 3 is minimal. So, I think we can just do this in one go like Fabian is suggesting.

private[chisel3] object VerifEnsureIntrinsic {
def apply(label: Option[String] = None)(prop: Bool, enable: Option[Bool])(implicit sourceInfo: SourceInfo) =
VerifAssertLikeIntrinsic("ensure", label)(prop, enable)
}
Copy link
Member

Choose a reason for hiding this comment

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

In a follow-up patch, all of these factories could be combined into a single trait with an abstract def intrinsicName: String method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea, added #4711 to track.

@fabianschuiki fabianschuiki merged commit 1bba7e4 into chipsalliance:main Feb 20, 2025
15 checks passed
@fabianschuiki fabianschuiki deleted the add-require-ensure branch February 20, 2025 01:20
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.

3 participants