[HW] Encoding enum types and values
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 2.2k
- Forks
- 524
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 46
Description
With https://github.com/llvm/circt/pull/3452, rudimentary enum support is now available in CIRCT. However, this commit leaves encoding of the enum up to a lowering pass (which currently, in #3478, will leave this up to the synthesis tool).
Some things to consider in this domain:
### Base types
Specifying a base type for an enum should restrict the encoding space and be reflected in the emitted SV and by default, an enum should be emitted as an unsigned integer:
e.g.:
```mlir
hw.typedecl @myEnum : !hw.enum[i5]
hw.typedecl @myEnum2 : !hw.enum
```
emits as
```sv
typedef enum bit [4:0] {A, B, C} myEnum_t;
typedef enum unsigned integer {D, E, F} myEnum2_t;
```
### Encoding values:
Allow specifying user-defined encodings for enum fields in either binary or decimal.
```mlir
hw.typedecl @myEnum : !hw.enum[i3]
```
emits as
```sv
typedef enum bit [2:0] {A = 3'b001, B = 3'b010, C} myEnum_t;
```
In case an explicit base type has been defined, we should check whether the requested encoding fits within the specified bitvector.
**Q:** how do we handle invalid/partial encodings?
```mlir
hw.typedecl @myEnum : !hw.enum[i2]
```
Depending on how downstream lowering and tooling interprets the above, it may (incrementally assigned: `B==4, C==5`) or may not (assigned to available encodings `B==0, C==1`) be illegal. My hunch is that codifying something here can lead into a rabithole that may not be relevant for anyones immediate use-case. My suggestion would be to only verify that requested encoding values fit within the base type, and then let downstream tooling decide whether or not something is an invalid enum.
### Bitvector casting
Integer casting allows interpreting enums as bitvectors and vice versa:
```mlir
%0 = hw.constant 3 : i3 // A, B
%1 = hw.enum_cast %0 : i3 to !hw.enum[i3]
%2 = hw.enum_cast %1 : !hw.enum[i3] to i5
```
**Q**: Should we only allow bitcasting on enums with explicit base types? Or should enums by default be considered as having a `i32` base type unless explicitly specified?
### FSM encoding
Currently, FSM conversion is the only user of the `hw` enum type. In this conversion , we also have explicit awareness of where our state register is, and how we might want the synthesis tool to infer our state machine. FSM encoding attributes are generally supported across different tools ([vivado](https://docs.xilinx.com/r/en-US/ug901-vivado-synthesis/FSM_ENCODING), [quartus](https://www.intel.com/content/www/us/en/programmable/quartushelp/17.0/hdl/vlog/vlog_file_dir_syn_encoding.htm)) and it would be due diligence to consider whether such FSM encoding attributes are an inherent part of an enum type or if it is specific to the site which uses the enum type.
If part of the enum type, there could be 'smarts' which determine that some using ops (like `sv.reg`) needs to be emitted with an fsm encoding attribute:
```mlir
hw.typedecl @myEnum : !hw.enum['onehot']
%state_reg = sv.reg : !hw.enum
// emits as
typedef enum {A, B, C} myEnum_t;
(* fsm_encoding = "one_hot" *) myEnum_t state_reg ;
```
If not, the attribute could be attached directly to the using op, possibly as an attribute of the `fsm` dialect;
```mlir
hw.typedecl @myEnum : !hw.enum
%state_reg = sv.reg : !hw.enum attributes {fsm.encoding = 'onehot'}
```
Which is lowered to an appropriate SV attribute based on the target tooling:
```mlir
hw.typedecl @myEnum : !hw.enum
// circt-opt --lower-fsm-encodings="target=quartus"
%state_reg = sv.reg svattrs [#sv.attribute<"syn_encoding" = "one-hot">] : !hw.enum
// circt-opt --lower-fsm-encodings="target=vivado"
%state_reg = sv.reg svattrs [#sv.attribute<"fsm_encoding" = "one_hot">] : !hw.enum
```
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the HW enum type, the lowering pass, FSM conversion, and SystemVerilog emission described in the issue. Resolve the open design questions around base types, explicit encodings, casting, and FSM encoding attributes before implementing them. Done means enum encoding behavior and the division between enum types and use sites are specified and supported consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100