Type of issue: Bug Report
Please provide the steps to reproduce the problem:
Create an empty Chisel project, then add Foo.scala below:
package foo
import chisel3._
import chisel3.util._
// This is a bundle with nested direction
class BundleWithDirection extends Bundle {
val a = Input(UInt(3.W))
}
class Foo extends Module {
val io = IO(new Bundle{
// And I'd like to make it an input for this module
// For now this works smoothly
val in = new BundleWithDirection
val out = Output(UInt(3.W))
})
// In this example we'll simply delay the input for 1 cycle
val buffer = RegNext(io.in)
io.out := buffer.a
}
Then generate verilog code using (new ChiselStage).execute( ... ) with argument --target verilog
What is the current behavior?
firtool will throw the following error:
src/main/scala/Foo.scala:18:25: error: 'firrtl.reg' op result #0 must be a passive non-'const' base type that does not contain analog, but got '!firrtl.bundle<a flip: uint<3>>'
val buffer = RegNext(io.in)
^
src/main/scala/Foo.scala:18:25: note: see current operation: %3 = "firrtl.reg"(%arg0) <{annotations = [], name = "buffer", nameKind = #firrtl<name_kind interesting_name>}> : (!firrtl.clock) -> !firrtl.bundle<a flip: uint<3>>
What is the expected behavior?
The BundleWithDirection bundle only contains Input signal, so RegNext(io.in) should be able to generate verilog code like
reg [2:0] buffer_a; // src/main/scala/Foo.scala:18:25
always @(posedge clock) // src/main/scala/Foo.scala:12:7
buffer_a <= io_in_a; // src/main/scala/Foo.scala:18:25
assign io_out = buffer_a; // src/main/scala/Foo.scala:12:7, :18:25
Please tell us about your environment:
- version: 7.7.0
- OS: Linux <hostname> 6.8.0-124-generic #124~22.04.1-Ubuntu SMP x86_64 GNU/Linux
Other Information
The Chisel code above could generate fir code with --target chirrtl:
FIRRTL version 6.0.0
circuit Foo :%[[
{
"class":"firrtl.transforms.DedupGroupAnnotation",
"target":"~|Foo",
"group":"Foo"
}
]]
layer Verification, bind, "verification" :
layer Assert, bind, "verification/assert" :
layer Temporal, inline :
layer Assume, bind, "verification/assume" :
layer Temporal, inline :
layer Cover, bind, "verification/cover" :
layer Temporal, inline :
public module Foo : @[src/main/scala/Foo.scala 12:7]
input clock : Clock @[src/main/scala/Foo.scala 12:7]
input reset : UInt<1> @[src/main/scala/Foo.scala 12:7]
output io : { in : { flip a : UInt<3>}, out : UInt<3>} @[src/main/scala/Foo.scala 13:16]
reg buffer : { flip a : UInt<3>}, clock @[src/main/scala/Foo.scala 18:25]
connect buffer.a, io.in.a @[src/main/scala/Foo.scala 18:25]
connect io.out, buffer.a @[src/main/scala/Foo.scala 19:12]
It seems that the Input in Chisel code is interpeted as output io : { in : { flip a : UInt<3>}, ...}, and the RegNext clones the type flip a: UInt<3>, which is considered a non-passive signal by firtool, causing it unable to connect buffer.a with io.in.a
This problem persists with val buffer = Reg(chiselTypeOf(io.in))
When removing the flip in reg buffer : { flip a : UInt<3>}, clock, the firtool is able to generate the correct verilog code, indicating that this issue might be fixed by removing the direction notation in fir reg.
What is the use case for changing the behavior?
Bundles with nested direction works well for grouping signals with similar functionalities together, e.g. gathering all the signals that connects to another specific module, so that they're easy to find, and can be connected using one line of source <> dest.
When a bundle consists of signal with the same direction, it should be able to use with RegNext or Reg for convenient buffering.
Type of issue: Bug Report
Please provide the steps to reproduce the problem:
Create an empty Chisel project, then add
Foo.scalabelow:Then generate verilog code using
(new ChiselStage).execute( ... )with argument--target verilogWhat is the current behavior?
firtoolwill throw the following error:What is the expected behavior?
The
BundleWithDirectionbundle only containsInputsignal, soRegNext(io.in)should be able to generate verilog code likePlease tell us about your environment:
- version:
7.7.0- OS:
Linux <hostname> 6.8.0-124-generic #124~22.04.1-Ubuntu SMP x86_64 GNU/LinuxOther Information
The Chisel code above could generate fir code with
--target chirrtl:It seems that the
Inputin Chisel code is interpeted asoutput io : { in : { flip a : UInt<3>}, ...}, and theRegNextclones the typeflip a: UInt<3>, which is considered a non-passive signal byfirtool, causing it unable to connectbuffer.awithio.in.aThis problem persists with
val buffer = Reg(chiselTypeOf(io.in))When removing the
flipinreg buffer : { flip a : UInt<3>}, clock, thefirtoolis able to generate the correct verilog code, indicating that this issue might be fixed by removing the direction notation in firreg.What is the use case for changing the behavior?
Bundles with nested direction works well for grouping signals with similar functionalities together, e.g. gathering all the signals that connects to another specific module, so that they're easy to find, and can be connected using one line of
source <> dest.When a bundle consists of signal with the same direction, it should be able to use with
RegNextorRegfor convenient buffering.