chipsalliance / chipsalliance/chisel

Esoteric Reverse

Open
#1,200 0 comments 1 reaction 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.