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

are zero field/variant enum/bundle types legal #208

Open
programmerjake opened this issue Apr 25, 2024 · 4 comments
Open

are zero field/variant enum/bundle types legal #208

programmerjake opened this issue Apr 25, 2024 · 4 comments

Comments

@programmerjake
Copy link

afaict the specification doesn't specify if you can have an enumeration type with no variants {||} (the grammar allows it, but I'm not sure if that's intentional, since uninhabited types behave very oddly).
The specification says you can have a bundle type with no fields but the grammar doesn't allow it:

firrtl-spec/spec.md

Lines 4406 to 4415 in 9b0357e

(* Bundle Types *)
type_bundle = "{" , type_bundle_field , { type_bundle_field } , "}" ;
type_bundle_field = [ "flip" ] , id , ":" , type ;
(* Vec Types *)
type_vec = type , "[" , int , "]" ;
(* Enum Types *)
type_enum = "{|" , { type_enum_alt } , "|}" ;
type_enum_alt = id, [ ":" , type_constable ] ;

@mmaloney-sf
Copy link
Collaborator

This is a fair point.

Presumably, it should work as a 0-width type. (Just like UInt<0>). But I don't know where the firtool implementation sits with this.

@jackkoenig
Copy link
Collaborator

jackkoenig commented Apr 25, 2024

While a Bundle with no fields is a zero-width type, an enumeration would be a zero-width type with one variant. I don't know if firtool implements it either but it's a bit different than UInt<0> since the numerical value of this 0-bit value is user-defined rather than 0 (I know you @mmaloney-sf are just saying it should work, not that it's the same, I just suspect the correct behavior isn't implemented yet). I'm not sure what a zero-variant enumeration is since it would need log2(0) bits to represent it 🤯.

@mmaloney-sf
Copy link
Collaborator

Ah. I made a mistake here.

The bitwidth of a type should be log2 of the number of values it supports. Eg, a UInt<1> has two values, UInt<1>(0) and UInt<1>(1), and thus has a bitwidth of log2(2) = 1.

So the bitwidth of an empty type (such as an empty enum) should be undefined, as log2(0) is undefined.

So yeah. Scratch what I said earlier.

@programmerjake
Copy link
Author

In Rust, zero-variant enums are generally size zero (though not currently guaranteed). they are types which can not ever have any values of that type, so they're used for code paths that never return (not very applicable to firrtl) or can't happen (somewhat useful in firrtl).

e.g. in Rust you can have Result<MyTy, Infallible> to indicate a type which can never be the error variant. the firrtl equivalent would be {|Ok: MyTy, Err: {||}|}

see docs for Result and Infallible

that kind of enum would be useful in generic code where you instantiate some generic module that can handle an error, e.g. by propagating the error value to some output, but in your specific use it never will handle an error so supplying an empty enum type as the error type can help by making firrtl automatically remove all error handling code and data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants