Hello,
If you can share a little bit more about what you're trying to do, maybe we can provide an alternative way to achieve the same goal?
The reason why you cannot return in when blocks is that fundamentally, using Chisel is writing software to construct a hardware rather than writing code to be behaviorally synthesized. It is important to think about Chisel as explicitly describing the wires, registers, memories, and logic in your circuit. You can then leverage the power of Scala to parameterize and write program to perform this hardware construction.
We usually differentiate between *elaboration* and the actual generated *hardware*. For example
val w = Wire(UInt(8.W))
if (condition) {
w := 10.U
} else {
w := 20.U
}
This snippet uses "if" which is a Scala construct matching if in any other language. Since if is a Scala construct, this condition is evaluated when the program is generating our hardware. That means, that statically, either the "then" or the "else" block executes. In our actual hardware, in simulation or in silicon, wire is either always 10, or always 20. Assuming condition is true, this corresponds to the Verilog:
wire [7:0] w = 10;
Note that 20 is no where to be seen, only the "then" block of the "if" was executed when the Scala program ran.
Alternatively, if we consider Chisel's "when" construct, this is a syntactically convenient way to create mux(es):
val w = Wire(UInt(8.W))
when (condition) {
w := 10.U
} .otherwise {
w := 20.U
}
In this case, rather than condition being an elaboration-time (ie. statically known) Boolean, it is a Chisel Bool, a signal or wire actually present in the generated hardware. Thus this corresponds to the Verilog:
wire condition = // something
wire [7:0] w = condition ? 10 : 20;
Now, you may be wondering what any of this has to do with *return*. The important thing to know is that return is a Scala construct, so it is relevant at elaboration time but has no realization in hardware. If you look at the when/.otherwise block above, *both* blocks execute when the Scala program runs. You can think about the when block as recording "condition" as the select signal for a Mux, and then registering 10 and 20 as the true and false inputs for the Mux. Thus, as far as Scala is concerned, both the when block, and the .otherwise block execute. The key insight is the conditional is preserved through to the hardware, whereas on the if, else only one side or the other makes it through.
I hope this explanation helps at least a little bit. But in any case, please let us know what you're trying to do and we'll do our best to guide you in the right direction!