-
Notifications
You must be signed in to change notification settings - Fork 404
Labels
SeqInvolving the `seq` dialectInvolving the `seq` dialect
Description
After doing some more experiments with use of inline layers, I hit an issue with LowerSeqToSV producing invalid IR. Consider the following:
sv.macro.decl @C
hw.hierpath private @A [@Foo::@clock]
hw.hierpath private @B [@Foo::@reset]
hw.module private @Bar() {
%c1_i10 = hw.constant 1 : i10
%c0_i10 = hw.constant 0 : i10
%0 = sv.xmr.ref @B : !hw.inout<i1>
%1 = sv.read_inout %0 : !hw.inout<i1>
%2 = seq.to_clock %1
%3 = sv.xmr.ref @A : !hw.inout<i1>
%4 = sv.read_inout %3 : !hw.inout<i1>
sv.ifdef @C {
%count = seq.firreg %5 clock %2 reset async %4, %c0_i10 : i10
%5 = comb.add bin %count, %c1_i10 : i10
}
hw.output
}
hw.module.extern @Foo(
in %clock : !seq.clock {hw.exportPort = #hw<innerSym@clock>},
in %reset : i1 {hw.exportPort = #hw<innerSym@reset>}
)Compile this creates illegal IR:
$ circt-opt Foo.mlir --pass-pipeline='builtin.module(lower-seq-to-sv)'
reduced.0.mlir:13:14: error: operand #0 does not dominate this use
%count = seq.firreg %5 clock %2 reset async %4, %c0_i10 : i10
^
reduced.0.mlir:13:14: note: see current operation: "sv.bpassign"(%17, %4) : (!hw.inout<i10>, i10) -> ()
reduced.0.mlir:13:14: note: operand defined here (op is neither in a parent nor in a child region)The final MLIR is:
#loc = loc("reduced.0.mlir":19:6)
#loc1 = loc("reduced.0.mlir":20:6)
"builtin.module"() ({
"sv.macro.decl"() <{sym_name = "SYNTHESIS"}> : () -> ()
"sv.macro.decl"() <{sym_name = "VERILATOR"}> : () -> ()
"emit.fragment"() <{sym_name = "RANDOM_INIT_FRAGMENT"}> ({
"sv.verbatim"() <{format_string = "// Standard header to adapt well known macros for register randomization.", symbols = []}> : () -> ()
"sv.verbatim"() <{format_string = "\0A// RANDOM may be set to an expression that produces a 32-bit random unsigned value.", symbols = []}> : () -> ()
"sv.ifdef"() <{cond = #sv<macro.ident @RANDOM>}> ({
^bb0:
}, {
"sv.macro.def"() <{format_string = "$random", macroName = @RANDOM, symbols = []}> : () -> ()
}) : () -> ()
"sv.verbatim"() <{format_string = "\0A// Users can define INIT_RANDOM as general code that gets injected into the\0A// initializer block for modules with registers.", symbols = []}> : () -> ()
"sv.ifdef"() <{cond = #sv<macro.ident @INIT_RANDOM>}> ({
^bb0:
}, {
"sv.macro.def"() <{format_string = "", macroName = @INIT_RANDOM, symbols = []}> : () -> ()
}) : () -> ()
"sv.verbatim"() <{format_string = "\0A// If using random initialization, you can also define RANDOMIZE_DELAY to\0A// customize the delay used, otherwise 0.002 is used.", symbols = []}> : () -> ()
"sv.ifdef"() <{cond = #sv<macro.ident @RANDOMIZE_DELAY>}> ({
^bb0:
}, {
"sv.macro.def"() <{format_string = "0.002", macroName = @RANDOMIZE_DELAY, symbols = []}> : () -> ()
}) : () -> ()
"sv.verbatim"() <{format_string = "\0A// Define INIT_RANDOM_PROLOG_ for use in our modules below.", symbols = []}> : () -> ()
"sv.ifdef"() <{cond = #sv<macro.ident @INIT_RANDOM_PROLOG_>}> ({
^bb0:
}, {
"sv.ifdef"() <{cond = #sv<macro.ident @RANDOMIZE>}> ({
"sv.ifdef"() <{cond = #sv<macro.ident @VERILATOR>}> ({
"sv.macro.def"() <{format_string = "`INIT_RANDOM", macroName = @INIT_RANDOM_PROLOG_, symbols = []}> : () -> ()
}, {
"sv.macro.def"() <{format_string = "`INIT_RANDOM #`RANDOMIZE_DELAY begin end", macroName = @INIT_RANDOM_PROLOG_, symbols = []}> : () -> ()
}) : () -> ()
}, {
"sv.macro.def"() <{format_string = "", macroName = @INIT_RANDOM_PROLOG_, symbols = []}> : () -> ()
}) : () -> ()
}) : () -> ()
}) : () -> ()
"emit.fragment"() <{sym_name = "RANDOM_INIT_REG_FRAGMENT"}> ({
"sv.verbatim"() <{format_string = "\0A// Include register initializers in init blocks unless synthesis is set", symbols = []}> : () -> ()
"sv.ifdef"() <{cond = #sv<macro.ident @RANDOMIZE>}> ({
^bb0:
}, {
"sv.ifdef"() <{cond = #sv<macro.ident @RANDOMIZE_REG_INIT>}> ({
"sv.macro.def"() <{format_string = "", macroName = @RANDOMIZE, symbols = []}> : () -> ()
}, {
}) : () -> ()
}) : () -> ()
"sv.ifdef"() <{cond = #sv<macro.ident @SYNTHESIS>}> ({
^bb0:
}, {
"sv.ifdef"() <{cond = #sv<macro.ident @ENABLE_INITIAL_REG_>}> ({
^bb0:
}, {
"sv.macro.def"() <{format_string = "", macroName = @ENABLE_INITIAL_REG_, symbols = []}> : () -> ()
}) : () -> ()
}) : () -> ()
"sv.verbatim"() <{format_string = "", symbols = []}> : () -> ()
}) : () -> ()
"sv.macro.decl"() <{sym_name = "ENABLE_INITIAL_REG_"}> : () -> ()
"sv.macro.decl"() <{sym_name = "ENABLE_INITIAL_MEM_"}> : () -> ()
"sv.macro.decl"() <{sym_name = "FIRRTL_BEFORE_INITIAL"}> : () -> ()
"sv.macro.decl"() <{sym_name = "FIRRTL_AFTER_INITIAL"}> : () -> ()
"sv.macro.decl"() <{sym_name = "RANDOMIZE_REG_INIT"}> : () -> ()
"sv.macro.decl"() <{sym_name = "RANDOMIZE"}> : () -> ()
"sv.macro.decl"() <{sym_name = "RANDOMIZE_DELAY"}> : () -> ()
"sv.macro.decl"() <{sym_name = "RANDOM"}> : () -> ()
"sv.macro.decl"() <{sym_name = "INIT_RANDOM"}> : () -> ()
"sv.macro.decl"() <{sym_name = "INIT_RANDOM_PROLOG_"}> : () -> ()
"sv.macro.decl"() <{sym_name = "C"}> : () -> ()
"hw.hierpath"() <{namepath = [#hw.innerNameRef<@Foo::@clock>], sym_name = "A"}> {sym_visibility = "private"} : () -> ()
"hw.hierpath"() <{namepath = [#hw.innerNameRef<@Foo::@reset>], sym_name = "B"}> {sym_visibility = "private"} : () -> ()
"hw.hierpath"() <{namepath = [#hw.innerNameRef<@Bar::@count>], sym_name = "Bar_count"}> : () -> ()
"hw.module"() <{module_type = !hw.modty<>, parameters = [], sym_name = "Bar"}> ({
%0 = "hw.constant"() <{value = 0 : i0}> : () -> i0
%1 = "hw.constant"() <{value = true}> : () -> i1
%2 = "hw.constant"() <{value = false}> : () -> i1
%3 = "hw.constant"() <{value = 1 : i10}> : () -> i10
%4 = "hw.constant"() <{value = 0 : i10}> : () -> i10
%5 = "sv.xmr.ref"() <{ref = @B, verbatimSuffix = ""}> : () -> !hw.inout<i1>
%6 = "sv.read_inout"(%5) : (!hw.inout<i1>) -> i1
%7 = "sv.xmr.ref"() <{ref = @A, verbatimSuffix = ""}> : () -> !hw.inout<i1>
%8 = "sv.read_inout"(%7) : (!hw.inout<i1>) -> i1
"sv.ifdef"() <{cond = #sv<macro.ident @C>}> ({
%17 = "sv.reg"() <{inner_sym = #hw<innerSym@count>, name = "count"}> : () -> !hw.inout<i10>
%18 = "sv.read_inout"(%17) : (!hw.inout<i10>) -> i10
%19 = "comb.add"(%18, %3) <{twoState}> : (i10, i10) -> i10
"sv.always"(%6, %8) <{events = [0 : i32, 0 : i32]}> ({
"sv.if"(%8) ({
"sv.passign"(%17, %4) : (!hw.inout<i10>, i10) -> ()
}, {
"sv.passign"(%17, %19) : (!hw.inout<i10>, i10) -> ()
}) : (i1) -> ()
}) : (i1, i1) -> ()
}, {
}) : () -> ()
"sv.ifdef"() <{cond = #sv<macro.ident @ENABLE_INITIAL_REG_>}> ({
"sv.ordered"() ({
"sv.ifdef"() <{cond = #sv<macro.ident @FIRRTL_BEFORE_INITIAL>}> ({
"sv.verbatim"() <{format_string = "`FIRRTL_BEFORE_INITIAL", symbols = []}> : () -> ()
}, {
}) : () -> ()
"sv.initial"() ({
"sv.ifdef.procedural"() <{cond = #sv<macro.ident @INIT_RANDOM_PROLOG_>}> ({
"sv.verbatim"() <{format_string = "`INIT_RANDOM_PROLOG_", symbols = []}> : () -> ()
}, {
}) : () -> ()
"sv.ifdef.procedural"() <{cond = #sv<macro.ident @RANDOMIZE_REG_INIT>}> ({
%9 = "sv.logic"() <{name = "_RANDOM"}> : () -> !hw.inout<uarray<1xi32>>
"sv.for"(%2, %1, %1) <{inductionVarName = "i"}> ({
^bb0(%arg0: i1):
%14 = "sv.macro.ref.expr.se"() <{macroName = @RANDOM}> : () -> i32
%15 = "comb.extract"(%arg0) <{lowBit = 0 : i32}> : (i1) -> i0
%16 = "sv.array_index_inout"(%9, %15) : (!hw.inout<uarray<1xi32>>, i0) -> !hw.inout<i32>
"sv.bpassign"(%16, %14) : (!hw.inout<i32>, i32) -> ()
}) : (i1, i1, i1) -> ()
%10 = "sv.array_index_inout"(%9, %0) : (!hw.inout<uarray<1xi32>>, i0) -> !hw.inout<i32>
"sv.ifdef.procedural"() <{cond = #sv<macro.ident @C>}> ({
%11 = "sv.xmr.ref"() <{ref = @Bar_count, verbatimSuffix = ""}> : () -> !hw.inout<i10>
%12 = "sv.read_inout"(%10) : (!hw.inout<i32>) -> i32
%13 = "comb.extract"(%12) <{lowBit = 0 : i32}> : (i32) -> i10
"sv.bpassign"(%11, %13) : (!hw.inout<i10>, i10) -> ()
}, {
}) : () -> ()
}, {
}) : () -> ()
"sv.if"(%8) ({
"sv.bpassign"(%17, %4) : (!hw.inout<i10>, i10) -> ()
}, {
}) : (i1) -> ()
}) : () -> ()
"sv.ifdef"() <{cond = #sv<macro.ident @FIRRTL_AFTER_INITIAL>}> ({
"sv.verbatim"() <{format_string = "`FIRRTL_AFTER_INITIAL", symbols = []}> : () -> ()
}, {
}) : () -> ()
}) : () -> ()
}, {
}) : () -> ()
"hw.output"() : () -> ()
}) {emit.fragments = [@RANDOM_INIT_REG_FRAGMENT, @RANDOM_INIT_FRAGMENT], sym_visibility = "private"} : () -> ()
"hw.module.extern"() <{module_type = !hw.modty<input clock : i1, input reset : i1>, parameters = [], per_port_attrs = [{hw.exportPort = #hw<innerSym@clock>}, {hw.exportPort = #hw<innerSym@reset>}], port_locs = [#loc, #loc1], sym_name = "Foo"}> ({
}) : () -> ()
}) : () -> ()Metadata
Metadata
Assignees
Labels
SeqInvolving the `seq` dialectInvolving the `seq` dialect