diff --git a/lib/Dialect/FIRRTL/Transforms/InferWidths.cpp b/lib/Dialect/FIRRTL/Transforms/InferWidths.cpp index c0502e44847f..b90ba40847ec 100644 --- a/lib/Dialect/FIRRTL/Transforms/InferWidths.cpp +++ b/lib/Dialect/FIRRTL/Transforms/InferWidths.cpp @@ -1353,6 +1353,17 @@ LogicalResult InferenceMapping::mapOperation(Operation *op) { op.getType()); }) + .Case([&](RefSubOp op) { + uint64_t fieldID = TypeSwitch( + op.getInput().getType().getType()) + .Case([](auto _) { return 1; }) + .Case([&](auto type) { + return type.getFieldID(op.getIndex()); + }); + unifyTypes(FieldRef(op.getResult(), 0), + FieldRef(op.getInput(), fieldID), op.getType()); + }) + // Arithmetic and Logical Binary Primitives .Case([&](auto op) { auto lhs = getExpr(op.getLhs()); diff --git a/test/Dialect/FIRRTL/infer-widths.mlir b/test/Dialect/FIRRTL/infer-widths.mlir index 0bf71d3e15b6..ece6da2db60e 100644 --- a/test/Dialect/FIRRTL/infer-widths.mlir +++ b/test/Dialect/FIRRTL/infer-widths.mlir @@ -819,15 +819,27 @@ firrtl.circuit "Foo" { // CHECK-LABEL: @SubRef // CHECK-SAME: out %x: !firrtl.probe> // CHECK-SAME: out %y: !firrtl.rwprobe> - firrtl.module private @SubRef(out %x: !firrtl.probe, out %y : !firrtl.rwprobe) { + // CHECK-SAME: out %bov_ref: !firrtl.rwprobe, 2>, b: uint<2>>> + firrtl.module private @SubRef(out %x: !firrtl.probe, out %y : !firrtl.rwprobe, out %bov_ref : !firrtl.rwprobe, b : uint>>) { // CHECK: firrtl.wire forceable : !firrtl.uint<2>, !firrtl.rwprobe> %w, %w_rw = firrtl.wire forceable : !firrtl.uint, !firrtl.rwprobe + %bov, %bov_rw = firrtl.wire forceable : !firrtl.bundle, b flip: uint>, !firrtl.rwprobe, b : uint>> + firrtl.ref.define %bov_ref, %bov_rw : !firrtl.rwprobe, b : uint>> + %ref_w = firrtl.ref.send %w : !firrtl.uint firrtl.ref.define %x, %ref_w : !firrtl.probe firrtl.ref.define %y, %w_rw : !firrtl.rwprobe %c0_ui2 = firrtl.constant 0 : !firrtl.uint<2> firrtl.connect %w, %c0_ui2 : !firrtl.uint, !firrtl.uint<2> + + %bov_a = firrtl.subfield %bov[a] : !firrtl.bundle, b flip: uint> + %bov_a_1 = firrtl.subindex %bov_a[1] : !firrtl.vector + %bov_b = firrtl.subfield %bov[b] : !firrtl.bundle, b flip: uint> + + firrtl.connect %w, %c0_ui2 : !firrtl.uint, !firrtl.uint<2> + firrtl.connect %bov_a_1, %c0_ui2 : !firrtl.uint, !firrtl.uint<2> + firrtl.connect %bov_b, %c0_ui2 : !firrtl.uint, !firrtl.uint<2> } // CHECK-LABEL: @Ref // CHECK: out x: !firrtl.probe> @@ -835,11 +847,27 @@ firrtl.circuit "Foo" { // CHECK: firrtl.ref.resolve %sub_x : !firrtl.probe> // CHECK: firrtl.ref.resolve %sub_y : !firrtl.rwprobe> firrtl.module @Ref(out %r : !firrtl.uint, out %s : !firrtl.uint) { - %sub_x, %sub_y = firrtl.instance sub @SubRef(out x: !firrtl.probe, out y: !firrtl.rwprobe) + %sub_x, %sub_y, %sub_bov_ref = firrtl.instance sub @SubRef(out x: !firrtl.probe, out y: !firrtl.rwprobe, out bov_ref : !firrtl.rwprobe, b : uint>>) %res_x = firrtl.ref.resolve %sub_x : !firrtl.probe %res_y = firrtl.ref.resolve %sub_y : !firrtl.rwprobe firrtl.connect %r, %res_x : !firrtl.uint, !firrtl.uint firrtl.connect %s, %res_y : !firrtl.uint, !firrtl.uint + + // CHECK: !firrtl.rwprobe, 2>, b: uint<2>>> + %read_bov = firrtl.ref.resolve %sub_bov_ref : !firrtl.rwprobe, b : uint>> + // CHECK: !firrtl.rwprobe, 2>, b: uint<2>>> + %bov_ref_a = firrtl.ref.sub %sub_bov_ref[0] : !firrtl.rwprobe, b : uint>> + // CHECK: !firrtl.rwprobe, 2>> + %bov_ref_a_1 = firrtl.ref.sub %bov_ref_a[1] : !firrtl.rwprobe> + // CHECK: !firrtl.rwprobe, 2>, b: uint<2>>> + %bov_ref_b = firrtl.ref.sub %sub_bov_ref[1] : !firrtl.rwprobe, b : uint>> + + // CHECK: !firrtl.rwprobe, 2>> + %bov_a = firrtl.ref.resolve %bov_ref_a : !firrtl.rwprobe> + // CHECK: !firrtl.rwprobe> + %bov_a_1 = firrtl.ref.resolve %bov_ref_a_1 : !firrtl.rwprobe + // CHECK: !firrtl.rwprobe> + %bov_b = firrtl.ref.resolve %bov_ref_b : !firrtl.rwprobe } // CHECK-LABEL: @ForeignTypes