chipsalliance / chipsalliance/chisel
Result of operator ## cannot be assigned to
- Dominant language
- Scala
- Stars
- 4.8k
- Forks
- 658
- Avg merge
- 18h 59m
- Merged PRs (30d)
- 14
Description
**Type of issue**: bug report | feature request
**Impact**: API addition (no impact on existing code)
**Development Phase**: proposal
**What is the current behavior?**
Assume two kinds of Blackbox modules, `Slave` and `Master`. Let their interfaces be denoted by `SlaveIf` and `MasterIf`. Now, consider the case where you want to connect two `Master` instances to one of the `Slave` instances like in the following code:
```scala
class SlaveIf extends Bundle {
val inp = Input(UInt(4.W))
val outp = Output(UInt(4.W))
}
class MasterIf extends Bundle {
val inp = Output(UInt(2.W))
val outp = Input(UInt(2.W))
}
class Slave extends BlackBox {
val io = IO(new SlaveIf)
}
class Master extends BlackBox {
val io = IO(new MasterIf)
}
class Tlf extends Module {
val io = IO(new Bundle {
val fnord = Input(UInt(4.W))
})
val xbar = Module(new Slave)
val mst1 = Module(new Master)
val mst2 = Module(new Master)
xbar.io.inp <> (mst1.io.inp ## mst2.io.inp) // works
xbar.io.outp <> (mst1.io.outp ## mst1.io.outp) // !!!!not working!!!!
}
```
`xbar.io.inp <> (mst1.io.inp ## mst2.io.inp)` will roughly produce `assign xbar_inp = {mst1_inp,mst2_inp};` in the Verilog file, but the last line will produce the following runtime exception
```
Exception in thread "main" chisel3.internal.ChiselException: internal error: attempted to generate LHS ref to ReadOnlyBinding OpBinding(chisel_test.Tlf@1dbb650b,None)
at ... ()
at chisel_test.Tlf.(App.scala:38)
at chisel_test.App$.$anonfun$main$1(App.scala:46)
at ... ()
at ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)
```
Essentially it says that the result of a `##` operator is not writable.
This is overly conservative. Sure, the result of the `+` Operator on UInt cannot be written to, but the result of `##` can be.
**What is the expected behavior?**
The code should produce three module instances, some wires and the following two assignments
```
assign xbar_inp = {mst1_inp,mst2_inp};
assign {mst1_outp, mst2_outp} = xbar_outp
```
**Environment:**
- Chisel version: 3.5.2
- Latest macOS
Contributor guide
Research direction
Start by reproducing the issue with the Slave, Master, and Tlf example in the report using Chisel 3.5.2, then trace how the ## result is classified during the <> connection. Done means the example elaborates without the ReadOnlyBinding exception and emits assignments equivalent to the two shown in the report.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100