chipsalliance / chipsalliance/chisel

Datawidth problem of iteration counter in for loop

Open
#2,187 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Scala
Stars
4.8k
Forks
658
Avg merge
18h 59m
Merged PRs (30d)
14

Description

**Type of issue**: bug report

**Impact**: unknown

**Development Phase**: request

**Other information**

I'm new to chisel, I'm not sure whether it's a bug or a feature, but I don't think it is a good idea to use different data widths for iteration counter in for loop.

**If the current behavior is a bug, please provide the steps to reproduce the problem:**

The data width of the counter in for loop is not fixed (I thought it to be log2(range) or log2(range)+1).

Following code can reproduce.
```
class Top() extends Module{
val io = IO(new Bundle{
val data = Input(UInt(32.W))
val out1 = Output(UInt(64.W))
val out2 = Output(UInt(64.W))
val out3 = Output(UInt(64.W))
val out4 = Output(UInt(64.W))
})
val reg = RegInit(VecInit(Seq.fill(4)(0.U(64.W))))
for(i <- 0 until 4){
reg(i) := (i.U+1.U) * io.data
}
io.out1 := reg(0)
io.out2 := reg(1)
io.out3 := reg(2)
io.out4 := reg(3)
}
```
Generated Verilog is as follows:
```
reg [63:0] reg_0; // @[Top.scala 17:26]
reg [63:0] reg_1; // @[Top.scala 17:26]
reg [63:0] reg_2; // @[Top.scala 17:26]
reg [63:0] reg_3; // @[Top.scala 17:26]
wire [32:0] _reg_0_T_2 = 1'h1 * io_data; // @[Top.scala 20:46]
wire [32:0] _reg_1_T_2 = 1'h0 * io_data; // @[Top.scala 20:46]
wire [33:0] _reg_2_T_2 = 2'h3 * io_data; // @[Top.scala 20:46]
wire [33:0] _reg_3_T_2 = 2'h0 * io_data; // @[Top.scala 20:46]
assign io_out1 = reg_0; // @[Top.scala 23:17]
assign io_out2 = reg_1; // @[Top.scala 24:17]
assign io_out3 = reg_2; // @[Top.scala 25:17]
assign io_out4 = reg_3; // @[Top.scala 26:17]
always @(posedge clock) begin
if (reset) begin // @[Top.scala 17:26]
reg_0 <= 64'h0; // @[Top.scala 17:26]
end else begin
reg_0 <= {{31'd0}, _reg_0_T_2}; // @[Top.scala 20:33]
end
if (reset) begin // @[Top.scala 17:26]
reg_1 <= 64'h0; // @[Top.scala 17:26]
end else begin
reg_1 <= {{31'd0}, _reg_1_T_2}; // @[Top.scala 20:33]
end
if (reset) begin // @[Top.scala 17:26]
reg_2 <= 64'h0; // @[Top.scala 17:26]
end else begin
reg_2 <= {{30'd0}, _reg_2_T_2}; // @[Top.scala 20:33]
end
if (reset) begin // @[Top.scala 17:26]
reg_3 <= 64'h0; // @[Top.scala 17:26]
end else begin
reg_3 <= {{30'd0}, _reg_3_T_2}; // @[Top.scala 20:33]
end
end
```
**What is the current behavior?**
Data width of `i.U` is different for 4 iterations, thus the result of (i.U+1.U) is not what I expected
![image](https://user-images.githubusercontent.com/33260712/137684994-19603c64-327b-4e6c-88eb-a5badd30ff81.png)

Although it's better to use `+&` instead of `+`, I think the various data width of the counter "i" is confusing.

**What is the expected behavior?**
Fixed data width of `i`.
**Please tell us about your environment:**

- version: `3.4.4`

**What is the use case for changing the behavior?**

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.