-
Notifications
You must be signed in to change notification settings - Fork 615
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
asUInt packing inconsistent for Bundles with type parameters #4223
Comments
I'm shocked this hasn't come up before, but yeah this is a pretty big bug in Bundle field ordering. The order of fields in a Bundle is defined by the order the actual objects representing the fields were constructed (which in most cases matches Bundle field order, but as shown in the issue, may not). Using the order fields were constructed is legacy behavior from before we really had a way to determine field order. We can determine field order now in the compiler plugin so we can fix this. Here is an example using the latest release (6.4.0) showing the issue (and how by-name generator parameters interact with it): //> using scala "2.13.12"
//> using dep "org.chipsalliance::chisel:6.4.0"
//> using plugin "org.chipsalliance:::chisel-plugin:6.4.0"
//> using options "-unchecked", "-deprecation", "-language:reflectiveCalls", "-feature", "-Xcheckinit", "-Xfatal-warnings", "-Ywarn-dead-code", "-Ywarn-unused", "-Ymacro-annotations"
import chisel3._
// _root_ disambiguates from package chisel3.util.circt if user imports chisel3.util._
import _root_.circt.stage.ChiselStage
class Bundle1(gen: => UInt) extends Bundle {
val a = UInt(8.W)
val b = gen
val c = UInt(8.W)
}
class Bundle2(gen: UInt) extends Bundle {
val a = UInt(8.W)
val b = gen
val c = UInt(8.W)
}
class Foo extends Module {
val in0 = IO(Input(new Bundle1(UInt(8.W))))
val in1 = IO(Input(new Bundle2(UInt(8.W))))
val out0 = IO(Output(UInt(24.W)))
val out1 = IO(Output(UInt(24.W)))
out0 := in0.asUInt
out1 := in1.asUInt
}
object Main extends App {
println(
ChiselStage.emitSystemVerilog(
gen = new Foo,
firtoolOpts = Array("-disable-all-randomization", "-strip-debug-info")
)
)
} This gives: // Generated by CIRCT firtool-1.62.0
module Foo(
input clock,
reset,
input [7:0] in0_a,
in0_b,
in0_c,
in1_b,
in1_a,
in1_c,
output [23:0] out0,
out1
);
assign out0 = {in0_a, in0_b, in0_c};
assign out1 = {in1_b, in1_a, in1_c};
endmodule |
Fixing this involves:
|
what is the "right order" here? follow up, what's the right order for the bundle elements
|
The right order is the order of the fields in the definition of the Bundle, so for your |
The fix will be in the next 7.0 line release (probably 7.0.0-M3 or 7.0.0-RC1) |
Type of issue: Bug Report
Please provide the steps to reproduce the problem:
The code below defines a Bundle with type parameters and four fields, all resolving to type
Bool()
.Generating Verilog for this code:
results in that
a
,b
,c
, andd
(all bools) are packed differently inout1
andout2
in the generated Verilog file:What is the current behavior?
Packing of Bundle fields depend on:
Types.D
defined beforeTypes.B
in the code aboveTypeBD = new Types, TypeC = Bool()
gives different result thanTypeC = Bool(), TypeBD = new Types
What is the expected behavior?
Packing order should only be influenced by the order of the declaration of the Bundle fields. In the example above I expect both outputs to be assigned to
{a, b, c, d}
Please tell us about your environment:
Other Information
What is the use case for changing the behavior?
Interfacing with pure Verilog modules requires the field positions of a bundle to be controllable. Having to write an explicit mapping function from Bundle fields to bits of a bit vector shouldn't be needed.
The text was updated successfully, but these errors were encountered: