Constant to generate 'x and 'z (#730)

Constant op for x and z
This commit is contained in:
Andrew Lenharth 2021-03-05 15:21:38 -07:00 committed by GitHub
parent b26a9afcbd
commit ca0a68f45d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 13 deletions

View File

@ -25,3 +25,27 @@ def TextualValueOp : SVOp<"textual_value", [NoSideEffect]> {
let results = (outs AnySignlessInteger:$result);
let assemblyFormat = "$string attr-dict `:` type($result)";
}
def ConstantXOp : SVOp<"constantX", [NoSideEffect]> {
let summary = "A constant of value 'x'";
let description = [{
This operation produces a constant value of 'x'. This 'x' follows the
System Verilog rules for 'x' propagation.
}];
let arguments = (ins);
let results = (outs RTLIntegerType:$result);
let assemblyFormat = " attr-dict `:` type($result)";
}
def ConstantZOp : SVOp<"constantZ", [NoSideEffect]> {
let summary = "A constant of value 'z'";
let description = [{
This operation produces a constant value of 'z'. This 'z' follows the
System Verilog rules for 'z' propagation.
}];
let arguments = (ins);
let results = (outs RTLIntegerType:$result);
let assemblyFormat = " attr-dict `:` type($result)";
}

View File

@ -28,7 +28,8 @@ public:
return TypeSwitch<Operation *, ResultType>(op)
.template Case<
// Expressions
ReadInOutOp, ArrayIndexInOutOp, TextualValueOp,
ReadInOutOp, ArrayIndexInOutOp, TextualValueOp, ConstantXOp,
ConstantZOp,
// Declarations.
RegOp, WireOp,
// Control flow.
@ -74,9 +75,11 @@ public:
HANDLE(WireOp, Unhandled);
// Expressions
HANDLE(TextualValueOp, Unhandled)
HANDLE(ReadInOutOp, Unhandled);
HANDLE(ArrayIndexInOutOp, Unhandled);
HANDLE(TextualValueOp, Unhandled);
HANDLE(ConstantXOp, Unhandled);
HANDLE(ConstantZOp, Unhandled);
// Control flow.
HANDLE(IfDefOp, Unhandled);

View File

@ -24,7 +24,8 @@ using namespace sv;
/// Return true if the specified operation is an expression.
bool sv::isExpression(Operation *op) {
return isa<sv::TextualValueOp>(op) || isa<sv::GetModportOp>(op) ||
isa<sv::ReadInterfaceSignalOp>(op);
isa<sv::ReadInterfaceSignalOp>(op) || isa<sv::ConstantXOp>(op) ||
isa<sv::ConstantZOp>(op);
}
//===----------------------------------------------------------------------===//

View File

@ -722,6 +722,8 @@ private:
SubExprInfo visitSV(GetModportOp op);
SubExprInfo visitSV(ReadInterfaceSignalOp op);
SubExprInfo visitSV(TextualValueOp op);
SubExprInfo visitSV(ConstantXOp op);
SubExprInfo visitSV(ConstantZOp op);
// Noop cast operators.
SubExprInfo visitSV(ReadInOutOp op) {
@ -1104,6 +1106,16 @@ SubExprInfo ExprEmitter::visitSV(TextualValueOp op) {
return {Unary, IsUnsigned};
}
SubExprInfo ExprEmitter::visitSV(ConstantXOp op) {
os << op.getType().getWidth() << "'bx";
return {Unary, IsUnsigned};
}
SubExprInfo ExprEmitter::visitSV(ConstantZOp op) {
os << op.getType().getWidth() << "'bz";
return {Unary, IsUnsigned};
}
SubExprInfo ExprEmitter::visitTypeOp(ConstantOp op) {
bool isNegated = false;
const APInt &value = op.getValue();

View File

@ -15,7 +15,9 @@ rtl.module @test1(%arg0: i1, %arg1: i1, %arg8: i8) {
sv.ifdef "SYNTHESIS" {
} else {
%tmp = sv.textual_value "PRINTF_COND_" : i1
%tmp2 = comb.and %tmp, %arg1 : i1
%tmpx = sv.constantX : i1
%tmpz = sv.constantZ : i1
%tmp2 = comb.and %tmp, %tmpx, %tmpz, %arg1 : i1
sv.if %tmp2 {
sv.fwrite "Hi\n"
}
@ -32,12 +34,14 @@ rtl.module @test1(%arg0: i1, %arg1: i1, %arg8: i8) {
// CHECK-NEXT: sv.ifdef "SYNTHESIS" {
// CHECK-NEXT: } else {
// CHECK-NEXT: %0 = sv.textual_value "PRINTF_COND_" : i1
// CHECK-NEXT: %1 = comb.and %0, %arg1 : i1
// CHECK-NEXT: sv.if %1 {
// CHECK-NEXT: %1 = sv.constantX : i1
// CHECK-NEXT: %2 = sv.constantZ : i1
// CHECK-NEXT: %3 = comb.and %0, %1, %2, %arg1 : i1
// CHECK-NEXT: sv.if %3 {
// CHECK-NEXT: sv.fwrite "Hi\0A"
// CHECK-NEXT: }
// CHECK-NEXT: sv.if %1 {
// CHECK-NEXT: sv.fwrite "%x"(%1) : i1
// CHECK-NEXT: sv.if %3 {
// CHECK-NEXT: sv.fwrite "%x"(%3) : i1
// CHECK-NEXT: } else {
// CHECK-NEXT: sv.fwrite "There\0A"
// CHECK-NEXT: }

View File

@ -9,18 +9,20 @@ rtl.module @M1(%clock : i1, %cond : i1, %val : i8) {
sv.always posedge %clock {
sv.ifdef "SYNTHESIS" {
} else {
// CHECK-NEXT: if (PRINTF_COND_ & cond)
// CHECK-NEXT: if (PRINTF_COND_ & 1'bx & 1'bz & cond)
%tmp = sv.textual_value "PRINTF_COND_" : i1
%tmp2 = comb.and %tmp, %cond : i1
sv.if %tmp2 {
%tmp1 = sv.constantX : i1
%tmp2 = sv.constantZ : i1
%tmp3 = comb.and %tmp, %tmp1, %tmp2, %cond : i1
sv.if %tmp3 {
// CHECK-NEXT: $fwrite(32'h80000002, "Hi\n");
sv.fwrite "Hi\n"
}
// CHECK-NEXT: if (!(clock | cond))
// CHECK-NEXT: $fwrite(32'h80000002, "Bye\n");
%tmp3 = comb.or %clock, %cond : i1
sv.if %tmp3 {
%tmp4 = comb.or %clock, %cond : i1
sv.if %tmp4 {
} else {
sv.fwrite "Bye\n"
}