[SV] Rename sv.textual_value to sv.verbatim.expr to align with sv.verbatim.

This commit is contained in:
Chris Lattner 2021-03-15 08:17:36 -07:00
parent 35c0fc7d38
commit f6f59c971d
10 changed files with 40 additions and 39 deletions

View File

@ -299,7 +299,7 @@ The major classes of operations you'll find are:
1) Access to verification constructs with `sv.assert`, `sv.assume`, and
`sv.cover`.
1) Escape hatches that allow direct integration of textual expressions
(`sv.textual_value`) and full statements (`sv.verbatim`).
(`sv.verbatim.expr`) and full statements (`sv.verbatim`).
These operations are designed to directly model the syntax of the SystemVerilog
language and to be easily printable by the ExportVerilog pass. While there are

View File

@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//
def TextualValueOp : SVOp<"textual_value", [NoSideEffect]> {
def VerbatimExprOp : SVOp<"verbatim.expr", [NoSideEffect]> {
let summary = "Expression that expands to a value given SystemVerilog text";
let description = [{
This operation produces a typed value expressed by a string of
@ -18,9 +18,10 @@ def TextualValueOp : SVOp<"textual_value", [NoSideEffect]> {
only sensible as Verilog text.
The text string is expected to have the highest precedence, so you should
include parentheses in the string if it isn't a single token.
include parentheses in the string if it isn't a single token. This is also
assumed to not have side effects (use sv.verbatim) if you need them.
sv.textual_value allows operand substitutions with {{0}} syntax.
sv.verbatim.expr allows operand substitutions with {{0}} syntax.
}];
let arguments = (ins StrAttr:$string, Variadic<AnyType>:$operands);

View File

@ -28,7 +28,7 @@ public:
return TypeSwitch<Operation *, ResultType>(op)
.template Case<
// Expressions
ReadInOutOp, ArrayIndexInOutOp, TextualValueOp, ConstantXOp,
ReadInOutOp, ArrayIndexInOutOp, VerbatimExprOp, ConstantXOp,
ConstantZOp,
// Declarations.
RegOp, WireOp,
@ -77,7 +77,7 @@ public:
// Expressions
HANDLE(ReadInOutOp, Unhandled);
HANDLE(ArrayIndexInOutOp, Unhandled);
HANDLE(TextualValueOp, Unhandled);
HANDLE(VerbatimExprOp, Unhandled);
HANDLE(ConstantXOp, Unhandled);
HANDLE(ConstantZOp, Unhandled);

View File

@ -1586,7 +1586,7 @@ void FIRRTLLowering::emitRandomizePrologIfNeeded() {
void FIRRTLLowering::initializeRegister(Value reg, Value resetSignal) {
// Construct and return a new reference to `RANDOM.
auto randomVal = [&](Type type) {
return builder.create<sv::TextualValueOp>(type, "`RANDOM");
return builder.create<sv::VerbatimExprOp>(type, "`RANDOM");
};
// Randomly initialize everything in the register. If the register
@ -1838,7 +1838,7 @@ LogicalResult FIRRTLLowering::visitDecl(MemOp op) {
if (!llvm::isPowerOf2_64(depth)) {
auto addrWidth = addr.getType().getIntOrFloatBitWidth();
auto depthCst = getOrCreateIntConstant(addrWidth, depth);
value = builder.create<sv::TextualValueOp>(
value = builder.create<sv::VerbatimExprOp>(
value.getType(),
"RANDOMIZE_GARBAGE_ASSIGN_BOUND_CHECK({{0}}, {{1}}, {{2}})",
ValueRange{addr, value, depthCst});
@ -1916,7 +1916,7 @@ LogicalResult FIRRTLLowering::visitDecl(MemOp op) {
if (depth == 1) { // Don't emit a for loop for one element.
auto type = sv::getInOutElementType(reg.getType());
type = sv::getAnyRTLArrayElementType(type);
auto randomVal = builder.create<sv::TextualValueOp>(type, "`RANDOM");
auto randomVal = builder.create<sv::VerbatimExprOp>(type, "`RANDOM");
auto zero = getOrCreateIntConstant(1, 0);
auto subscript = builder.create<sv::ArrayIndexInOutOp>(reg, zero);
builder.create<sv::BPAssignOp>(subscript, randomVal);
@ -2513,7 +2513,7 @@ LogicalResult FIRRTLLowering::visitStmt(PrintFOp op) {
addToIfDefProceduralBlock("SYNTHESIS", std::function<void()>(), [&]() {
// Emit an "sv.if '`PRINTF_COND_ & cond' into the #ifndef.
Value ifCond =
builder.create<sv::TextualValueOp>(cond.getType(), "`PRINTF_COND_");
builder.create<sv::VerbatimExprOp>(cond.getType(), "`PRINTF_COND_");
ifCond = builder.createOrFold<comb::AndOp>(ifCond, cond);
addIfProceduralBlock(ifCond, [&]() {
@ -2540,7 +2540,7 @@ LogicalResult FIRRTLLowering::visitStmt(StopOp op) {
addToIfDefProceduralBlock("SYNTHESIS", std::function<void()>(), [&]() {
// Emit an "sv.if '`STOP_COND_ & cond' into the #ifndef.
Value ifCond =
builder.create<sv::TextualValueOp>(cond.getType(), "`STOP_COND_");
builder.create<sv::VerbatimExprOp>(cond.getType(), "`STOP_COND_");
ifCond = builder.createOrFold<comb::AndOp>(ifCond, cond);
addIfProceduralBlock(ifCond, [&]() {
// Emit the sv.fatal or sv.finish.

View File

@ -24,7 +24,7 @@ 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) ||
return isa<sv::VerbatimExprOp>(op) || isa<sv::GetModportOp>(op) ||
isa<sv::ReadInterfaceSignalOp>(op) || isa<sv::ConstantXOp>(op) ||
isa<sv::ConstantZOp>(op);
}

View File

@ -849,7 +849,7 @@ private:
SubExprInfo visitSV(GetModportOp op);
SubExprInfo visitSV(ReadInterfaceSignalOp op);
SubExprInfo visitSV(TextualValueOp op);
SubExprInfo visitSV(VerbatimExprOp op);
SubExprInfo visitSV(ConstantXOp op);
SubExprInfo visitSV(ConstantZOp op);
@ -1240,7 +1240,7 @@ SubExprInfo ExprEmitter::visitSV(ReadInterfaceSignalOp op) {
return {Selection, IsUnsigned};
}
SubExprInfo ExprEmitter::visitSV(TextualValueOp op) {
SubExprInfo ExprEmitter::visitSV(VerbatimExprOp op) {
emitTextWithSubstitutions(op.string(), op, [&](Value operand) {
emitSubExpr(operand, LowestPrecedence, OOLBinary);
});

View File

@ -233,12 +233,12 @@ firrtl.circuit "Simple" {
// CHECK: sv.always posedge %clock {
// CHECK-NEXT: sv.ifdef.procedural "SYNTHESIS" {
// CHECK-NEXT: } else {
// CHECK-NEXT: [[TV:%.+]] = sv.textual_value "`PRINTF_COND_" : () -> i1
// CHECK-NEXT: [[TV:%.+]] = sv.verbatim.expr "`PRINTF_COND_" : () -> i1
// CHECK-NEXT: [[AND:%.+]] = comb.and [[TV]], %reset
// CHECK-NEXT: sv.if [[AND]] {
// CHECK-NEXT: sv.fwrite "No operands!\0A"
// CHECK-NEXT: }
// CHECK-NEXT: %5 = sv.textual_value "`PRINTF_COND_" : () -> i1
// CHECK-NEXT: %5 = sv.verbatim.expr "`PRINTF_COND_" : () -> i1
// CHECK-NEXT: %6 = comb.and %5, %reset : i1
// CHECK-NEXT: sv.if %6 {
// CHECK-NEXT: sv.fwrite "Hi %x %x\0A"(%2, %b) : i5, i4
@ -272,7 +272,7 @@ firrtl.circuit "Simple" {
// CHECK-NEXT: sv.always posedge %clock1 {
// CHECK-NEXT: sv.ifdef.procedural "SYNTHESIS" {
// CHECK-NEXT: } else {
// CHECK-NEXT: %0 = sv.textual_value "`STOP_COND_" : () -> i1
// CHECK-NEXT: %0 = sv.verbatim.expr "`STOP_COND_" : () -> i1
// CHECK-NEXT: %1 = comb.and %0, %reset : i1
// CHECK-NEXT: sv.if %1 {
// CHECK-NEXT: sv.fatal
@ -284,7 +284,7 @@ firrtl.circuit "Simple" {
// CHECK-NEXT: sv.always posedge %clock2 {
// CHECK-NEXT: sv.ifdef.procedural "SYNTHESIS" {
// CHECK-NEXT: } else {
// CHECK-NEXT: %0 = sv.textual_value "`STOP_COND_" : () -> i1
// CHECK-NEXT: %0 = sv.verbatim.expr "`STOP_COND_" : () -> i1
// CHECK-NEXT: %1 = comb.and %0, %reset : i1
// CHECK-NEXT: sv.if %1 {
// CHECK-NEXT: sv.finish
@ -428,7 +428,7 @@ firrtl.circuit "Simple" {
// CHECK-NEXT: sv.initial {
// CHECK-NEXT: sv.verbatim "`INIT_RANDOM_PROLOG_"
// CHECK-NEXT: sv.ifdef.procedural "RANDOMIZE_REG_INIT" {
// CHECK-NEXT: %3 = sv.textual_value "`RANDOM" : () -> i2
// CHECK-NEXT: %3 = sv.verbatim.expr "`RANDOM" : () -> i2
// CHECK-NEXT: sv.bpassign %count, %3 : i2
// CHECK-NEXT: }
// CHECK-NEXT: }
@ -483,9 +483,9 @@ firrtl.circuit "Simple" {
// CHECK-NEXT: sv.ifdef.procedural "RANDOMIZE_REG_INIT" {
// CHECK-NEXT: sv.if %reset {
// CHECK-NEXT: } else {
// CHECK-NEXT: %8 = sv.textual_value "`RANDOM" : () -> i32
// CHECK-NEXT: %8 = sv.verbatim.expr "`RANDOM" : () -> i32
// CHECK-NEXT: sv.bpassign %reg, %8 : i32
// CHECK-NEXT: %9 = sv.textual_value "`RANDOM" : () -> i32
// CHECK-NEXT: %9 = sv.verbatim.expr "`RANDOM" : () -> i32
// CHECK-NEXT: sv.bpassign %reg2, %9 : i32
// CHECK-NEXT: }
// CHECK-NEXT: }
@ -559,7 +559,7 @@ firrtl.circuit "Simple" {
// COM: --------------------------------------------------------------------
// CHECK-NEXT: [[data_inout:%.+]] = sv.array_index_inout %_M[%c0_i4]
// CHECK-NEXT: [[data:%.+]] = sv.read_inout [[data_inout]]
// CHECK-NEXT: = sv.textual_value "RANDOMIZE_GARBAGE_ASSIGN_BOUND_CHECK({{.*}})"(%c0_i4, [[data]], %c-4_i4) : (i4, i42, i4) -> i42
// CHECK-NEXT: = sv.verbatim.expr "RANDOMIZE_GARBAGE_ASSIGN_BOUND_CHECK({{.*}})"(%c0_i4, [[data]], %c-4_i4) : (i4, i42, i4) -> i42
// COM: Write port.
// COM: --------------------------------------------------------------------
@ -698,25 +698,25 @@ firrtl.circuit "Simple" {
// CHECK: sv.ifdef "SYNTHESIS" {
// CHECK: } else {
// CHECK: %[[r_en_0:.+]] = sv.array_index_inout %memory_r_en_pipe[%false]
// CHECK: %[[random:.+]] = sv.textual_value "`RANDOM"
// CHECK: %[[random:.+]] = sv.verbatim.expr "`RANDOM"
// CHECK: sv.bpassign %[[r_en_0]], %[[random]]
// CHECK: %[[r_addr_0:.+]] = sv.array_index_inout %memory_r_addr_pipe[%false]
// CHECK: %[[random:.+]] = sv.textual_value "`RANDOM"
// CHECK: %[[random:.+]] = sv.verbatim.expr "`RANDOM"
// CHECK: sv.bpassign %[[r_addr_0]], %[[random]]
// CHECK: %[[r_addr_1:.+]] = sv.array_index_inout %memory_r_addr_pipe[%true]
// CHECK: %[[random:.+]] = sv.textual_value "`RANDOM"
// CHECK: %[[random:.+]] = sv.verbatim.expr "`RANDOM"
// CHECK: sv.bpassign %[[r_addr_1]], %[[random]]
// CHECK: %[[w_en_0:.+]] = sv.array_index_inout %memory_w_en_pipe[%false]
// CHECK: %[[random:.+]] = sv.textual_value "`RANDOM"
// CHECK: %[[random:.+]] = sv.verbatim.expr "`RANDOM"
// CHECK: sv.bpassign %[[w_en_0]], %[[random]]
// CHECK: %[[w_addr_0:.+]] = sv.array_index_inout %memory_w_addr_pipe[%false]
// CHECK: %[[random:.+]] = sv.textual_value "`RANDOM"
// CHECK: %[[random:.+]] = sv.verbatim.expr "`RANDOM"
// CHECK: sv.bpassign %[[w_addr_0]], %[[random]]
// CHECK: %[[w_mask_0:.+]] = sv.array_index_inout %memory_w_mask_pipe[%false]
// CHECK: %[[random:.+]] = sv.textual_value "`RANDOM"
// CHECK: %[[random:.+]] = sv.verbatim.expr "`RANDOM"
// CHECK: sv.bpassign %[[w_mask_0]], %[[random]]
// CHECK: %[[w_data_0:.+]] = sv.array_index_inout %memory_w_data_pipe[%false]
// CHECK: %[[random:.+]] = sv.textual_value "`RANDOM"
// CHECK: %[[random:.+]] = sv.verbatim.expr "`RANDOM"
// CHECK: sv.bpassign %[[w_data_0]], %[[random]]
// CHECK: }
}
@ -730,7 +730,7 @@ firrtl.circuit "Simple" {
// CHECK: %_M = sv.reg : !rtl.inout<uarray<12xi42>>
%_M_read = firrtl.mem Undefined {depth = 12 : i64, name = "_M", portNames = ["read"], readLatency = 0 : i32, writeLatency = 1 : i32} : !firrtl.bundle<addr: flip<uint<4>>, en: flip<uint<1>>, clk: flip<clock>, data: sint<42>>
// Read port.
// CHECK: sv.textual_value "RANDOMIZE_GARBAGE_ASSIGN_BOUND_CHECK
// CHECK: sv.verbatim.expr "RANDOMIZE_GARBAGE_ASSIGN_BOUND_CHECK
%6 = firrtl.subfield %_M_read("addr") : (!firrtl.bundle<addr: flip<uint<4>>, en: flip<uint<1>>, clk: flip<clock>, data: sint<42>>) -> !firrtl.flip<uint<4>>
firrtl.connect %6, %c0_ui1 : !firrtl.flip<uint<4>>, !firrtl.uint<1>
%7 = firrtl.subfield %_M_read("en") : (!firrtl.bundle<addr: flip<uint<4>>, en: flip<uint<1>>, clk: flip<clock>, data: sint<42>>) -> !firrtl.flip<uint<1>>

View File

@ -14,7 +14,7 @@ rtl.module @test1(%arg0: i1, %arg1: i1, %arg8: i8) {
sv.always posedge %arg0 {
sv.ifdef.procedural "SYNTHESIS" {
} else {
%tmp = sv.textual_value "PRINTF_COND_" : () -> i1
%tmp = sv.verbatim.expr "PRINTF_COND_" : () -> i1
%tmpx = sv.constantX : i1
%tmpz = sv.constantZ : i1
%tmp2 = comb.and %tmp, %tmpx, %tmpz, %arg1 : i1
@ -33,7 +33,7 @@ rtl.module @test1(%arg0: i1, %arg1: i1, %arg8: i8) {
// CHECK-NEXT: sv.always posedge %arg0 {
// CHECK-NEXT: sv.ifdef.procedural "SYNTHESIS" {
// CHECK-NEXT: } else {
// CHECK-NEXT: %0 = sv.textual_value "PRINTF_COND_" : () -> i1
// CHECK-NEXT: %0 = sv.verbatim.expr "PRINTF_COND_" : () -> i1
// CHECK-NEXT: %1 = sv.constantX : i1
// CHECK-NEXT: %2 = sv.constantZ : i1
// CHECK-NEXT: %3 = comb.and %0, %1, %2, %arg1 : i1

View File

@ -10,7 +10,7 @@ rtl.module @M1(%clock : i1, %cond : i1, %val : i8) {
sv.ifdef.procedural "SYNTHESIS" {
} else {
// CHECK-NEXT: if (PRINTF_COND_ & 1'bx & 1'bz & cond)
%tmp = sv.textual_value "PRINTF_COND_" : () -> i1
%tmp = sv.verbatim.expr "PRINTF_COND_" : () -> i1
%tmp1 = sv.constantX : i1
%tmp2 = sv.constantZ : i1
%tmp3 = comb.and %tmp, %tmp1, %tmp2, %cond : i1
@ -146,7 +146,7 @@ rtl.module @M1(%clock : i1, %cond : i1, %val : i8) {
%add = comb.add %val, %c42 : i8
%c42_2 = rtl.constant 42 : i8
%xor = comb.xor %val, %c42_2 : i8
%text = sv.textual_value "MACRO({{0}}, {{1}})" (%add, %xor): (i8,i8) -> i8
%text = sv.verbatim.expr "MACRO({{0}}, {{1}})" (%add, %xor): (i8,i8) -> i8
// CHECK-NEXT: $fwrite(32'h80000002, "M: %x\n", MACRO(val + 8'h2A, val ^ 8'h2A));
sv.fwrite "M: %x\n"(%text) : i8
@ -169,13 +169,13 @@ rtl.module @M1(%clock : i1, %cond : i1, %val : i8) {
// CHECK-NEXT: automatic logic _T_0;
// CHECK-EMPTY:
// CHECK-NEXT: _T = THING;
%thing = sv.textual_value "THING" : () -> i42
%thing = sv.verbatim.expr "THING" : () -> i42
// CHECK-NEXT: wire42 = _T;
sv.bpassign %wire42, %thing : i42
sv.ifdef.procedural "FOO" {
// CHECK-NEXT: `ifdef FOO
%c1 = sv.textual_value "\"THING\"" : () -> i1
%c1 = sv.verbatim.expr "\"THING\"" : () -> i1
// CHECK-NEXT: {{.+}} = "THING";
sv.fwrite "%d" (%c1) : i1
// CHECK-NEXT: fwrite(32'h80000002, "%d", {{.+}});
@ -240,7 +240,7 @@ rtl.module @M1(%clock : i1, %cond : i1, %val : i8) {
// CHECK-NEXT: `ifdef FOO
sv.ifdef "FOO" {
// CHECK-NEXT: wire {{.+}} = "THING";
%c1 = sv.textual_value "\"THING\"" : () -> i1
%c1 = sv.verbatim.expr "\"THING\"" : () -> i1
// CHECK-NEXT: initial begin
sv.initial {

View File

@ -315,7 +315,7 @@ rtl.module @Stop(%clock: i1, %reset: i1) {
sv.always posedge %clock {
sv.ifdef.procedural "SYNTHESIS" {
} else {
%0 = sv.textual_value "`STOP_COND_" : () -> i1
%0 = sv.verbatim.expr "`STOP_COND_" : () -> i1
%1 = comb.and %0, %reset : i1
sv.if %1 {
sv.fatal
@ -338,7 +338,7 @@ rtl.module @Print(%clock: i1, %reset: i1, %a: i4, %b: i4) {
%0 = comb.concat %false, %a : (i1, i4) -> i5
%1 = comb.shl %0, %c1_i5 : i5
sv.always posedge %clock {
%2 = sv.textual_value "`PRINTF_COND_" : () -> i1
%2 = sv.verbatim.expr "`PRINTF_COND_" : () -> i1
%3 = comb.and %2, %reset : i1
sv.if %3 {
sv.fwrite "Hi %x %x\0A"(%1, %b) : i5, i4