Skip to content

Commit cb04c6a

Browse files
committed
[Moore][ImportVerilog] Add SystemVerilog string.getc builtin
1 parent 4d81b97 commit cb04c6a

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

include/circt/Dialect/Moore/MooreOps.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2553,5 +2553,14 @@ def StringToLowerOp : StringBuiltin<"tolower"> {
25532553
let assemblyFormat = "$str attr-dict";
25542554
}
25552555

2556+
def StringGetCOp : StringBuiltin<"getc"> {
2557+
let summary = "Get a character from a string";
2558+
let description = [{
2559+
Returns the character at the specified index in the given string.
2560+
}];
2561+
let arguments = (ins StringType:$str, TwoValuedI32:$index);
2562+
let results = (outs TwoValuedI8:$result);
2563+
let assemblyFormat = "$str `[` $index `]` attr-dict";
2564+
}
25562565

25572566
#endif // CIRCT_DIALECT_MOORE_MOOREOPS

include/circt/Dialect/Moore/MooreTypes.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,13 @@ def TwoValuedI32 : MooreType<CPred<[{
521521
let builderCall = "IntType::getInt($_builder.getContext(), 32)";
522522
}
523523

524+
// A 32-bit two-valued integer.
525+
def TwoValuedI8 : MooreType<CPred<[{
526+
moore::isIntType($_self, 8, moore::Domain::TwoValued)
527+
}]>, "8-bit two-valued integer type", "moore::IntType"> {
528+
let builderCall = "IntType::getInt($_builder.getContext(), 8)";
529+
}
530+
524531
// A 32-bit real value.
525532
def RealF32 : MooreType<CPred<[{
526533
moore::isRealType($_self, 32)

lib/Conversion/ImportVerilog/Expressions.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,7 @@ struct RvalueExprVisitor : public ExprVisitor {
14171417

14181418
FailureOr<Value> result;
14191419
Value value;
1420+
Value value2;
14201421

14211422
// $sformatf() and $sformat look like system tasks, but we handle string
14221423
// formatting differently from expression evaluation, so handle them
@@ -1451,6 +1452,14 @@ struct RvalueExprVisitor : public ExprVisitor {
14511452
result = context.convertSystemCallArity1(subroutine, loc, value);
14521453
break;
14531454

1455+
case (2):
1456+
value = context.convertRvalueExpression(*args[0]);
1457+
value2 = context.convertRvalueExpression(*args[1]);
1458+
if (!value || !value2)
1459+
return {};
1460+
result = context.convertSystemCallArity2(subroutine, loc, value, value2);
1461+
break;
1462+
14541463
default:
14551464
break;
14561465
}
@@ -2517,6 +2526,20 @@ Context::convertSystemCallArity1(const slang::ast::SystemSubroutine &subroutine,
25172526
return systemCallRes();
25182527
}
25192528

2529+
FailureOr<Value>
2530+
Context::convertSystemCallArity2(const slang::ast::SystemSubroutine &subroutine,
2531+
Location loc, Value value1, Value value2) {
2532+
auto systemCallRes =
2533+
llvm::StringSwitch<std::function<FailureOr<Value>()>>(subroutine.name)
2534+
.Case("getc",
2535+
[&]() -> Value {
2536+
return moore::StringGetCOp::create(builder, loc, value1,
2537+
value2);
2538+
})
2539+
.Default([&]() -> Value { return {}; });
2540+
return systemCallRes();
2541+
}
2542+
25202543
// Resolve any (possibly nested) SymbolRefAttr to an op from the root.
25212544
static mlir::Operation *resolve(Context &context, mlir::SymbolRefAttr sym) {
25222545
return context.symbolTable.lookupNearestSymbolFrom(context.intoModuleOp, sym);

lib/Conversion/ImportVerilog/ImportVerilogInternals.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,11 @@ struct Context {
238238
convertSystemCallArity1(const slang::ast::SystemSubroutine &subroutine,
239239
Location loc, Value value);
240240

241+
/// Convert system function calls with arity-2.
242+
FailureOr<Value>
243+
convertSystemCallArity2(const slang::ast::SystemSubroutine &subroutine,
244+
Location loc, Value value1, Value value2);
245+
241246
/// Convert system function calls within properties and assertion with a
242247
/// single argument.
243248
FailureOr<Value> convertAssertionSystemCallArity1(

test/Conversion/ImportVerilog/builtins.sv

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ function void dummyA(int x); endfunction
99
function void dummyB(real x); endfunction
1010
function void dummyC(shortreal x); endfunction
1111
function void dummyD(string x); endfunction
12+
function void dummyE(byte x); endfunction
1213

1314
// IEEE 1800-2017 § 20.2 "Simulation control system tasks"
1415
// CHECK-LABEL: func.func private @SimulationControlBuiltins(
@@ -386,11 +387,14 @@ endmodule
386387

387388
// CHECK-LABEL: func.func private @StringBuiltins(
388389
// CHECK-SAME: [[STR:%.+]]: !moore.string
389-
function void StringBuiltins(string string_in);
390+
// CHECK-SAME: [[INT:%.+]]: !moore.i32
391+
function void StringBuiltins(string string_in, int int_in);
390392
// CHECK: [[LEN:%.+]] = moore.string.len [[STR]]
391393
dummyA(string_in.len());
392394
// CHECK: [[LEN:%.+]] = moore.string.toupper [[STR]]
393395
dummyD(string_in.toupper());
394396
// CHECK: [[LEN:%.+]] = moore.string.tolower [[STR]]
395397
dummyD(string_in.tolower());
398+
// CHECK: [[CHAR:%.+]] = moore.string.getc [[STR]]{{\[}}[[INT]]]
399+
dummyE(string_in.getc(int_in));
396400
endfunction

0 commit comments

Comments
 (0)