chisel icon indicating copy to clipboard operation
chisel copied to clipboard

asUInt packing inconsistent for Bundles with type parameters

Open maxbjurling opened this issue 1 year ago • 4 comments

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:

import chisel3._
import _root_.circt.stage.ChiselStage

class Types {
  val D = Bool()
  val B = Bool()
}

class InBundle [T <: Types, U <: Data] (TypeC: U, TypeBD: T) extends Bundle {
  val a = Bool()
  val b = TypeBD.B
  val c = TypeC
  val d = TypeBD.D
}

class BundleTest extends Module() {
  val io = IO (new Bundle {
    val in1  =  Input(new InBundle (TypeBD = new Types, TypeC  = Bool()))
    val in2  =  Input(new InBundle (TypeC  = Bool(),    TypeBD = new Types))
    val out1 = Output(UInt(in1.getWidth.W))
    val out2 = Output(UInt(in2.getWidth.W))
  })
    io.out1 := io.in1.asUInt
    io.out2 := io.in2.asUInt
  }

object VerilogMain extends App {
  ChiselStage.emitSystemVerilogFile(new BundleTest)
}

results in that a, b, c, and d (all bools) are packed differently in out1 and out2 in the generated Verilog file:

assign io_out1 = {io_in1_d, io_in1_b, io_in1_c, io_in1_a}; // {d, b, c, a}
assign io_out2 = {io_in2_c, io_in2_d, io_in2_b, io_in2_a}; // {c, d, b, a}

What is the current behavior?

Packing of Bundle fields depend on:

  • the order of type definitions
    • e.g. Types.D defined before Types.B in the code above
  • the order in which parameters are assigned at the creation of the Bundle
    • TypeBD = new Types, TypeC = Bool() gives different result than TypeC = Bool(), TypeBD = new Types
  • the order of declaring the fields of the Bundle

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:

  • version: 6.3.0

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.

maxbjurling avatar Jun 27 '24 11:06 maxbjurling