Skip to content

[FIRRTL][LowerToHW] use-before-def with inline layer #8461

Open
@seldridge

Description

@seldridge

The following fails to compile due to a use-before-def created by LowerToHW:

FIRRTL version 5.1.0
circuit Foo :
  layer Verif, inline :

  public module Foo :
    input clock : Clock
    input reset : UInt<1>
    input enq : { flip ready : UInt<1>, valid : UInt<1>, bits : UInt<8>}
    output deq : { flip ready : UInt<1>, valid : UInt<1>, bits : UInt<8>}

    connect deq, enq
    wire valid : UInt<1>
    wire valid_rwprobe : RWProbe<UInt<1>, Verif>
    define valid_rwprobe = rwprobe(valid)
    connect valid, enq.valid
    connect deq.valid, valid
    skip
    layerblock Verif :
      regreset go_c_value : UInt<2>, clock, reset, UInt<2>(0h0)
      wire go : UInt<1>
      connect go, UInt<1>(0h0)
      when UInt<1>(0h0) :
        connect go_c_value, UInt<1>(0h0)
      else :
        when UInt<1>(0h1) :
          node go_wrap_wrap = eq(go_c_value, UInt<2>(0h3))
          node _go_wrap_value_T = add(go_c_value, UInt<1>(0h1))
          node _go_wrap_value_T_1 = tail(_go_wrap_value_T, 1)
          connect go_c_value, _go_wrap_value_T_1
          connect go, go_wrap_wrap
      when go :
        node has_been_reset = intrinsic(circt_has_been_reset : UInt<1>, clock, reset)
        node disable = eq(has_been_reset, UInt<1>(0h0))
        node _T = eq(disable, UInt<1>(0h0))
        force(clock, _T, valid_rwprobe, UInt<1>(0h0))

This is producing:

Foo.fir:19:7: error: operand #0 does not dominate this use
      regreset go_c_value : UInt<2>, clock, reset, UInt<2>(0h0)
      ^
Foo.fir:19:7: note: see current operation: %8 = "seq.firreg"(%14, %arg0, %arg1, %2) <{name = "go_c_value"}> {firrtl.random_init_start = 0 : ui64} : (i2, !seq.clock, i1, i2) -> i2
JackRWProbe.fir:28:37: note: operand defined here (op in the same block)
          node _go_wrap_value_T_1 = tail(_go_wrap_value_T, 1)

MLIR after failure:

#loc = loc("JackRWProbe.fir":8:11)
#loc1 = loc("JackRWProbe.fir":9:12)
"builtin.module"() ({
  "sv.macro.decl"() <{sym_name = "SYNTHESIS"}> : () -> ()
  "hw.hierpath"() <{namepath = [#hw.innerNameRef<@Foo::@sym>], sym_name = "xmrPath"}> {sym_visibility = "private"} : () -> ()
  "sv.macro.decl"() <{sym_name = "layer_Foo$Verif"}> : () -> ()
  "hw.module"() <{comment = "", module_type = !hw.modty<input clock : !seq.clock, input reset : i1, output enq_ready : i1, input enq_valid : i1, input enq_bits : i8, input deq_ready : i1, output deq_valid : i1, output deq_bits : i8>, parameters = [], per_port_attrs = [], result_locs = [#loc, #loc1, #loc1], sym_name = "Foo"}> ({
  ^bb0(%arg1: !seq.clock, %arg2: i1, %arg3: i1, %arg4: i8, %arg5: i1):
    %0 = "seq.from_clock"(%arg1) : (!seq.clock) -> i1
    %1 = "hw.constant"() <{value = -1 : i2}> : () -> i2
    %2 = "hw.constant"() <{value = 0 : i2}> : () -> i2
    %3 = "hw.constant"() <{value = true}> : () -> i1
    %4 = "hw.constant"() <{value = false}> : () -> i1
    %5 = "hw.wire"(%6) <{name = "deq_valid"}> : (i1) -> i1
    %6 = "hw.wire"(%arg3) <{inner_sym = #hw<innerSym@sym>, name = "valid"}> : (i1) -> i1
    "sv.ifdef"() <{cond = #sv<macro.ident @layer_Foo$Verif>}> ({
      %7 = "sv.xmr.ref"() <{ref = @xmrPath, verbatimSuffix = ""}> : () -> !hw.inout<i1>
      %8 = "seq.firreg"(%14, %arg1, %arg2, %2) <{name = "go_c_value"}> {firrtl.random_init_start = 0 : ui64} : (i2, !seq.clock, i1, i2) -> i2
      %9 = "hw.wire"(%10) <{name = "go"}> : (i1) -> i1
      %10 = "comb.icmp"(%8, %1) <{predicate = 0 : i64, twoState}> {sv.namehint = "go_wrap_wrap"} : (i2, i2) -> i1
      %11 = "comb.concat"(%4, %8) : (i1, i2) -> i3
      %12 = "comb.concat"(%2, %3) : (i2, i1) -> i3
      %13 = "comb.add"(%11, %12) <{twoState}> {sv.namehint = "_go_wrap_value_T"} : (i3, i3) -> i3
      %14 = "comb.extract"(%13) <{lowBit = 0 : i32}> {sv.namehint = "_go_wrap_value_T_1"} : (i3) -> i2
      %15 = "verif.has_been_reset"(%0, %arg2) <{async = false}> {sv.namehint = "has_been_reset"} : (i1, i1) -> i1
      %16 = "comb.and"(%9, %15) <{twoState}> : (i1, i1) -> i1
      "sv.ifdef"() <{cond = #sv<macro.ident @SYNTHESIS>}> ({
      ^bb0:
      }, {
        "sv.always"(%0) <{events = [0 : i32]}> ({
          "sv.if"(%16) ({
            "sv.force"(%7, %4) : (!hw.inout<i1>, i1) -> ()
          }, {
          }) : (i1) -> ()
        }) : (i1) -> ()
      }) : () -> ()
    }, {
    }) : () -> ()
    "hw.output"(%arg5, %5, %arg4) : (i1, i1, i8) -> ()
  }) : () -> ()
  "om.class"() <{fieldNames = [], fieldTypes = {}, formalParamNames = ["basepath"], sym_name = "Foo_Class"}> ({
  ^bb0(%arg0: !om.basepath):
    "om.class.fields"() <{field_locs = []}> : () -> ()
  }) : () -> ()
}) : () -> ()

Metadata

Metadata

Assignees

Labels

FIRRTLInvolving the `firrtl` dialectbugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions