chisel
chisel copied to clipboard
Create ChiselEnum1H where elements have one-hot encoding IDs
This PR adds a One-Hot encoded ChiselEnum where the elements have 1H instead of sequential IDs:
// It simplifies:
object InstructionType extends ChiselEnum {
val INST_I = Value((1 << 0).U)
val INST_S = Value((1 << 1).U)
val INST_B = Value((1 << 2).U)
val INST_U = Value((1 << 3).U)
val INST_J = Value((1 << 4).U)
val INST_Z = Value((1 << 5).U)
val INST_R = Value((1 << 6).U)
val IN_ERR = Value((1 << 7).U)
}
// into:
object InstructionType extends ChiselEnum1H {
val INST_I, INST_S, INST_U, INST_B, INST_J, INST_Z, INST_R, IN_ERR = Value
}
// Allowing the use in Mux1H for example as:
val selectorVal = Wire(UInt(InstructionType.getWidth.W))
selectorVal := InstructionType.INST_I.asUInt
val hotValue = chisel3.util.Mux1H(
selectorVal,
Seq(
2.U,
4.U,
8.U,
11.U,
15.U
)
)
The PR is for discussion and in case of greenlit, I'll add test cases for it.
Contributor Checklist
- [x] Did you add Scaladoc to every public function/method?
- [ ] Did you add at least one test demonstrating the PR?
- [x] Did you delete any extraneous printlns/debugging code?
- [x] Did you specify the type of improvement?
- [x] Did you add appropriate documentation in
docs/src
? - [x] Did you state the API impact?
- [x] Did you specify the code generation impact?
- [x] Did you request a desired merge strategy?
- [x] Did you add text to be included in the Release Notes for this change?
Type of Improvement
- documentation
- new feature/API
API Impact
The PR creates a ChiselEnum where elements have One-Hot IDs.
Backend Code Generation Impact
None.
Desired Merge Strategy
- Squash: The PR will be squashed and merged (choose this if you have no preference.
Release Notes
This PR adds a One-Hot encoded ChiselEnum where the elements have One-Hot IDs instead of sequential. This change pairs well with Mux1H
.
Reviewer Checklist (only modified by reviewer)
- [ ] Did you add the appropriate labels?
- [ ] Did you mark the proper milestone (Bug fix:
3.3.x
, [small] API extension:3.4.x
, API modification or big change:3.5.0
)? - [ ] Did you review?
- [ ] Did you check whether all relevant Contributor checkboxes have been checked?
- [ ] Did you mark as
Please Merge
?
My further question to this is: how to design the encoding API? 1H API implicitly contains an assertion: PopCount === 1.U
.
And how do we resolve this general encoding(ECC, 8b/10b, Gray Code, Hamming Code, etc...) issue?
Should we directly add corresponding assertion to this, which makes verification easier?
Or should we annotate the these encoding signal with an Annotation? and optionally add a Transform to these signals?
And how to propagate the encoding type? In bind
function or propagate in FIRRTL transform?
@carlosedp would you mind adding some test to demonstrate the usage?
Ping... news on this?
In the sample below, I really don't like the line to set the selector width...
object selector extends chisel3.experimental.ChiselEnum1H {
val s0, s1, s2, s3 = Value
}
val selectorVal = Wire(UInt(selector.getWidth.W)) // <--- don't like this
selectorVal := selector.s1.asUInt
val hotValue = chisel3.util.Mux1H(selectorVal.asUInt,
Seq(
2.U,
4.U,
8.U,
16.U,
))
Any ideas on improving this?
Any ideas on improving this?
Some thoughts:
- It seems to me like Mux1H should be changed to accept
ChiselEnum1H
instead of aUInt
directly. - You should be able to directly use your
selector
type as a type and thus write something likeval selectorVal = Wire(selector)
. - It might also make sense to have a
toIndex
function forChiselEnum1H
such that e.g.assert(selector.INST_S.toIndex === 1.U)
For 1, I could send another PR... ok? On 2, you mean the way it's already implemented I could use like this? Working on 3.
For 1, I could send another PR... ok?
I would prefer to see everything work together in a single PR.
On 2, you mean the way it's already implemented I could use like this?
Yes. Can you try to change your example and see if it works?
Working on 3.
Awesome
There it go! Have Mux1H accept ChiselEnum1H and added the toIndex function. Also example is pretty simple now:
object selector extends chisel3.experimental.ChiselEnum1H {
val s0, s1, s2, s3 = Value
}
val selectorVal = selector.s1
val hotValue = chisel3.util.Mux1H(selectorVal,
Seq(
2.U,
4.U,
8.U,
16.U,
))
// hotValue is 4.U