chipsalliance / chipsalliance/chisel
Esoteric Reverse
- Dominant language
- Scala
- Stars
- 4.8k
- Forks
- 658
- Avg merge
- 18h 59m
- Merged PRs (30d)
- 14
Description
The [existing algorithm for doing `Reverse`](https://github.com/freechipsproject/chisel3/blob/v3.2.0-RC2/src/main/scala/chisel3/util/Bitwise.scala#L83) is unexpectedly esoteric. This algorithm [also appears to stem from the original `chisel2`](https://github.com/ucb-bar/chisel2-deprecated/blob/9d9672bb69e9d6168ab3779f0ed543d5ad190dee/src/main/scala/ChiselUtil.scala#L110).
This algorithm, while correct and producing fine, efficient Verilog (QOR unverified by me, though) results in somewhat confusing Verilog for a user to look at.
Given the fact that this originates with Chisel2 (which was using a custom C++ backend) and that `CombineCats` is now a thing, I would like to see/propose a more straightforward/naive algorithm here that would make produce more readable Verilog. This would obviously be gated on not introducing a performance regression in simulation.
And I do note that if we had sub-word assignment a naive reverse would be very trivial.
### Example
Consider the following Chisel which uses the standard library `Reverse` to reverse `in` into `out` and a naive `BasicReverse` to reverse `in` to `out2`:
```scala
import chisel3._
import chisel3.util.Reverse
object BasicReverse {
def apply(a: UInt): UInt = VecInit(a.asBools.reverse).asUInt
}
class Baz(n: Int) extends MultiIOModule {
val in = IO(Input(UInt(n.W)))
val out = IO(Output(UInt(n.W)))
val out2 = IO(Output(UInt(n.W)))
out := Reverse(in)
out2 := BasicReverse(in)
}
(new ChiselStage).execute(Array("-X", "verilog"), Seq(ChiselGeneratorAnnotation(() => new Baz(4))))
```
This produces the following Verilog:
```
module Baz(
input clock,
input reset,
input [3:0] in,
output [3:0] out,
output [3:0] out2
);
wire [1:0] _T; // @[Bitwise.scala 108:18]
wire _T_1; // @[Bitwise.scala 108:18]
wire _T_2; // @[Bitwise.scala 108:44]
wire [1:0] _T_3; // @[Cat.scala 29:58]
wire [1:0] _T_4; // @[Bitwise.scala 108:44]
wire _T_5; // @[Bitwise.scala 108:18]
wire _T_6; // @[Bitwise.scala 108:44]
wire [1:0] _T_7; // @[Cat.scala 29:58]
wire _T_9; // @[ 43:40]
wire _T_10; // @[ 43:40]
wire _T_11; // @[ 43:40]
wire _T_12; // @[ 43:40]
wire [1:0] _T_14; // @[ 43:57]
wire [1:0] _T_15; // @[ 43:57]
assign _T = in[1:0]; // @[Bitwise.scala 108:18]
assign _T_1 = _T[0]; // @[Bitwise.scala 108:18]
assign _T_2 = _T[1]; // @[Bitwise.scala 108:44]
assign _T_3 = {_T_1,_T_2}; // @[Cat.scala 29:58]
assign _T_4 = in[3:2]; // @[Bitwise.scala 108:44]
assign _T_5 = _T_4[0]; // @[Bitwise.scala 108:18]
assign _T_6 = _T_4[1]; // @[Bitwise.scala 108:44]
assign _T_7 = {_T_5,_T_6}; // @[Cat.scala 29:58]
assign _T_9 = in[0]; // @[ 43:40]
assign _T_10 = in[1]; // @[ 43:40]
assign _T_11 = in[2]; // @[ 43:40]
assign _T_12 = in[3]; // @[ 43:40]
assign _T_14 = {_T_11,_T_12}; // @[ 43:57]
assign _T_15 = {_T_9,_T_10}; // @[ 43:57]
assign out = {_T_3,_T_7}; // @[ 51:7]
assign out2 = {_T_15,_T_14}; // @[ 52:8]
endmodule
```
**Type of issue**: feature request
**Impact**: API modification
**Development Phase**: proposal
**What is the current behavior?**
Less human-friendly Verilog when using `Reverse`.
**What is the expected behavior?**
A `Reverse` should look like how a human would write a `Reverse` in Verilog.
**Please tell us about your environment:**
- version: `3.2.0-RC2`
**What is the use case for changing the behavior?**
More readable Verilog.
Contributor guide
Research direction
Start with Reverse in src/main/scala/chisel3/util/Bitwise.scala, then review the linked Chisel2 implementation and the CombineCats context. Compare the existing generated Verilog with the BasicReverse example and investigate whether a more readable approach preserves simulation performance. Done means a decided algorithm produces human-readable Verilog without a performance regression.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100