llvm / circt

Circuit IR Compilers and Tools
https://circt.org
Other
1.67k stars 298 forks source link

FIRRTL to HW lowering involving type alias of bundle fails with "error: 'hw.struct_extract' op used as connect destination" #6303

Closed smarter closed 1 year ago

smarter commented 1 year ago

Given:

FIRRTL version 3.2.0
circuit Test:
  module Test:
    input i: { f: UInt<1>, b: UInt<1> }
    output o: { f: UInt<1>, b: UInt<1> }
    connect o, i

Then as expected I get:

% firtool --preserve-aggregate=all  test.fir
// Generated by CIRCT firtool-1.57.1
module Test(
  input  struct packed {logic f; logic b; } i,
  output struct packed {logic f; logic b; } o
);

  assign o = i;
endmodule

However, if I add a type alias:

FIRRTL version 3.2.0
circuit Test:
  type MyBundle = { f: UInt<1>, b: UInt<1> }
  module Test:
    input i: MyBundle
    output o: MyBundle
    connect o, i

Then firtool emits an error:

% firtool --preserve-aggregate=all  --scalarize-top-module=false test.fir
test.fir:7:5: error: 'hw.struct_extract' op used as connect destination
    connect o, i
    ^
test.fir:7:5: note: see current operation: %6 = "hw.struct_extract"(%2) {field = "f"} : (!hw.typealias<@Test__TYPESCOPE_::@MyBundle, !hw.struct<f: i1, b: i1>>) -> i1
test.fir:7:5: error: 'firrtl.strictconnect' op LowerToHW couldn't handle this operation
    connect o, i
    ^
test.fir:7:5: note: see current operation: "firrtl.strictconnect"(%7, %5) : (!firrtl.uint<1>, !firrtl.uint<1>) -> ()

The FIRParser output is:

%  firtool --ir-fir --preserve-aggregate=all  --scalarize-top-module=false test.fir
module {
  firrtl.circuit "Test" {
    firrtl.module @Test(in %i: !firrtl.alias<MyBundle, bundle<f: uint<1>, b: uint<1>>>, out %o: !firrtl.alias<MyBundle, bundle<f: uint<1>, b: uint<1>>>) {
      %0 = firrtl.subfield %i[f] : !firrtl.alias<MyBundle, bundle<f: uint<1>, b: uint<1>>>
      %1 = firrtl.subfield %o[f] : !firrtl.alias<MyBundle, bundle<f: uint<1>, b: uint<1>>>
      firrtl.strictconnect %1, %0 : !firrtl.uint<1>
      %2 = firrtl.subfield %i[b] : !firrtl.alias<MyBundle, bundle<f: uint<1>, b: uint<1>>>
      %3 = firrtl.subfield %o[b] : !firrtl.alias<MyBundle, bundle<f: uint<1>, b: uint<1>>>
      firrtl.strictconnect %3, %2 : !firrtl.uint<1>
    }
  }
}
uenoku commented 1 year ago

Thank you for a very nice reproducer! It should be fixed by https://github.com/llvm/circt/pull/6314/files. There is code that doesn't use firrtl type casts in MergeConnections.

smarter commented 1 year ago

Thanks!