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

Initial properties package and Property type. #3425

Merged

Conversation

mikeurbach
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

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.

@mikeurbach
Copy link
Contributor Author

This just sets the stage for properties. I'll send a PR next that will show the first Property types.

Should I add a page under src/docs for properties?

@mikeurbach
Copy link
Contributor Author

I filed a PR against this branch on my fork to show what the first properties additions look like: mikeurbach#1

@mwachs5
Copy link
Contributor

mwachs5 commented Jul 17, 2023

Should I add a page under src/docs for properties?

Yes, I think it would be good to put something under the explanations or cookbooks for them, depending on what kind of doc you plan to write.

When adding something there as a new page there are 3 things to update:

  1. write your new page
  2. add it in the ToC for that section, e.g if it's for explanations add it here, note it is in the order that you think a person should read it: https://github.com/chipsalliance/chisel/blob/main/docs/src/explanations/explanations.md
  3. add it to the website sidebar in the same order as 2 here, again if you are doing explanation then it would go in the corresponding slot here: https://github.com/chipsalliance/chisel/blob/main/website/docs/src/main/resources/microsite/data/menu.yml#L42

@mikeurbach mikeurbach force-pushed the mikeurbach/properties-initial branch from 78462fd to 44c5432 Compare July 19, 2023 22:19
@mikeurbach
Copy link
Contributor Author

This now includes #3429. I'd base this PR on that one for initial review, but this PR is on upstream chisel not my fork. I can open a PR within my fork for early review here if it would be helpful.

Comment on lines +17 to +24
private[chisel3] class PropertyType[T]

/** Companion object for PropertyType.
*
* Typeclass instances for valid Property types are defined here, so they will
* be in the implicit scope and available for users.
*/
private[chisel3] object PropertyType {}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know that these can really be package private and yet used in a public interface (on Property below), I think we will need to make these public.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In a later PR, where I actually add some typeclass instances here, it seems to work fine from the unit tests. Maybe I'm missing something--is there something I should test that would require this object to be public?

Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps it's changed in the last few days, but I don't see any unit tests calling this, only 1 that checks that it fails to compile. I think if you actually try to use this code from outside of the chisel3 package, you will get compile errors.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This draft PR on my fork is no longer in sync, but I think it indicates what I mean: https://github.com/mikeurbach/chisel3/pull/1/files#diff-4b64ebc257d840c404c27e41af276a1ae760940bdf80acf7f0cac225100fc944R20

There are tests in the chiselTests package that successfully create properties, and PropertyType is still package private. Maybe I'm missing something, but it seems like just Property needs to be public, and Scala implicit resolution did the rest.

@mikeurbach mikeurbach force-pushed the mikeurbach/properties-initial branch 7 times, most recently from 139b9e5 to acbe1cb Compare July 27, 2023 16:29
@mikeurbach
Copy link
Contributor Author

I rebased this on main and added a little section in the docs. I expect this will be fleshed out in future PRs as new property types are actually added. I think this is ready for a round of review @jackkoenig @mwachs5 .

* This entire package is currently very experimental, so expect some rough
* edges and rapid API evolution.
*/
package object properties {}
Copy link
Contributor

Choose a reason for hiding this comment

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

what is this for?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure if it's needed... I was just adding this boilerplate in case we want to define any functions in here later.

it should "fail to compile with unsupported Property types" in {
assertTypeError("""
class MyThing
val badProp = Property[MyThing]()
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you show the failing case where we try to propOut := propIn and you get the error message that its not legal? Such that in a subsequent PR it will be shown to now be legal?

Copy link
Contributor

Choose a reason for hiding this comment

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

But that same test would show that you can indeed have IO ports of property types?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well on this PR := is not even defined, so it will fail for that reason. Two PRs down the road there will be an example with both success and failure for :=.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok. i guess i thought this one was slated to land after #3442

Copy link
Contributor

Choose a reason for hiding this comment

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

but in this PR i should be able to have IO of Input, Output properties? Can that be shown?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i guess i thought this one was slated to land after

These are currently independent, there will be a future change to actually make properties connectable.

i should be able to have IO of Input, Output properties? Can that be shown?

Not in the current PR, since no actual types are being defined to work with Property (there are no typeclass instances for PropertyType). I'm trying to just stage these in small pieces with this piece being the initial boilerplate. In the next PR, you will be able to have an IO of Input or Output properties. If it would help, I can make draft PRs for the next two changes.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok, its fine. sounds like you are being cognizant of having the tests come in with the right change

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep trying to break this up into small pieces with tests for what is supported in each piece. This PR is mostly boilerplate, but we can at least test one error.

private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection): Unit = {
this.maybeAddToParentIds(target)
binding = target
val resolvedDirection = SpecifiedDirection.fromParent(parentDirection, specifiedDirection)
Copy link
Contributor

Choose a reason for hiding this comment

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

are you allowed to have Flipped properties?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm I mainly care about properties having Input/Output for their SpecifiedDirection and ActualDirection. When we get to property aggregates, I'm hoping to avoid having flips and have aggregate properties all point the same direction.

@mikeurbach
Copy link
Contributor Author

@jackkoenig @mwachs5 any other feedback on this initial PR? I have been using it in later patches in this series and it's working for me. For a preview, here's a draft PR of the next patch, based on this one: mikeurbach#1

@jackkoenig jackkoenig added the Feature New feature, will be included in release notes label Aug 3, 2023
@mikeurbach mikeurbach force-pushed the mikeurbach/properties-initial branch from acbe1cb to cdc09cd Compare August 3, 2023 18:22
@mikeurbach
Copy link
Contributor Author

I just force pushed this--no changes, but rebasing on main. That makes it easier for me to stack up the next three PRs, now that the required refactors are in main.


/** Companion object for PropertyType.
*
* Typeclass instances for valid Property types are defined here, so they will
Copy link
Contributor

Choose a reason for hiding this comment

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

Will this approach be flexible enough for user-defined struct properties? It seems like everything needs to be declared here to be supported.
I suppose if the plan is to have some sort of property aggregate base class this would work. Or just only supporting a Scala dictionary for that use case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it's a good question. I haven't thought about user-defined struct properties yet. We will have some kinds of aggregates, like a Scala Map as a property. Fairly soon, we will also add class/object to Chisel, which is sort of like a Module but only with Property typed ports. And an instance of a class (an object) will itself have a property type. So for user-defined "structs", I think we can support them that way.

In general, I think we will have to have a known set of types that can be used with Properties, if we want to take care of defining how they serialize to FIRRTL. So hopefully the above is enough extensibility, and we can still keep the set of possible Property types a sealed thing.

Comment on lines +48 to +60
/** Clone type by simply constructing a new Property[T].
*/
override def cloneType: this.type = new Property[T].asInstanceOf[this.type]

/** Clone type with extra information preserved.
*
* The only extra information present on a Property type is directionality.
*/
private[chisel3] override def cloneTypeFull: this.type = {
val clone = this.cloneType
clone.specifiedDirection = specifiedDirection
clone
}
Copy link
Contributor

Choose a reason for hiding this comment

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

If we go the more type-classy route, I'm wondering if .cloneType is something we're actually going to need. I know it's needed for now so not really a comment on this PR, but something we should keep in mind as we continue to flesh this API out.

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.

I feel like the next PR is going to be the more important one so let's just get this one in and continue fleshing this API out

@jackkoenig jackkoenig merged commit da90c5b into chipsalliance:main Aug 8, 2023
15 checks passed
@mikeurbach
Copy link
Contributor Author

Thanks @jackkoenig !

@mikeurbach mikeurbach added this to the 6.0 milestone Aug 10, 2023
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

4 participants