mirror of https://github.com/llvm/circt.git
[ExportVerilog] Make `hoistNonSideEffectExpr` hoist inout chains (#2405)
This commit fixes the crash of disallowLocalVars mode for the IR with array_index_inout/struct_field_inout and sv.read_inout. Currently `hoistNonSideEffectExpr` doesn't hoist array_index_inout and struct_field_inout because they are considered to be lvalues. This is true only if they are not read. They might become rvalues afterwards so we have to hoist them as well as read_inout op.
This commit is contained in:
parent
31d5b4864b
commit
6be754b850
|
@ -309,9 +309,11 @@ static bool rewriteSideEffectingExpr(Operation *op) {
|
|||
/// non-constant expressions out to the top level so they don't turn into local
|
||||
/// variable declarations.
|
||||
static bool hoistNonSideEffectExpr(Operation *op) {
|
||||
// Never hoist "always inline" expressions - they will never generate a
|
||||
// temporary and in fact must always be emitted inline.
|
||||
if (isExpressionAlwaysInline(op) && !isa<sv::ReadInOutOp>(op))
|
||||
// Never hoist "always inline" expressions except for inout stuffs - they will
|
||||
// never generate a temporary and in fact must always be emitted inline.
|
||||
if (isExpressionAlwaysInline(op) &&
|
||||
!(isa<sv::ReadInOutOp>(op) ||
|
||||
op->getResult(0).getType().isa<hw::InOutType>()))
|
||||
return false;
|
||||
|
||||
// Scan to the top of the region tree to find out where to move the op.
|
||||
|
|
|
@ -153,4 +153,23 @@ hw.module @EmittedDespiteDisallowed(%clock: i1, %reset: i1) {
|
|||
hw.output
|
||||
}
|
||||
|
||||
|
||||
// CHECK-LABEL: module ReadInoutAggregate(
|
||||
hw.module @ReadInoutAggregate(%clock: i1) {
|
||||
%register = sv.reg : !hw.inout<array<1xstruct<a: i32>>>
|
||||
sv.always posedge %clock {
|
||||
%c0_i16 = hw.constant 0 : i16
|
||||
%false = hw.constant false
|
||||
%0 = sv.array_index_inout %register[%false] : !hw.inout<array<1xstruct<a: i32>>>, i1
|
||||
%1 = sv.struct_field_inout %0["a"] : !hw.inout<struct<a: i32>>
|
||||
%2 = sv.read_inout %1 : !hw.inout<i32>
|
||||
%3 = comb.extract %2 from 0 : (i32) -> i16
|
||||
%4 = comb.concat %c0_i16, %3 : i16, i16
|
||||
sv.passign %1, %4 : i32
|
||||
}
|
||||
// DISALLOW: localparam [[T:.+]] = 1'h0;
|
||||
// DISALLOW-NEXT: wire [31:0] [[READ:.+]] = register{{\[}}[[T]]{{\]}}.a;
|
||||
// DISALLOW-NEXT: wire [31:0] [[CONCAT:.+]] = {16'h0, [[READ]][15:0]};
|
||||
// DISALLOW-NEXT: always @(
|
||||
// DISALLOW-NEXT: register{{\[}}[[T]]{{\]}}.a <= [[CONCAT]];
|
||||
hw.output
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue