From 59fb35e62c68353548d46dde14aae2884163f1a7 Mon Sep 17 00:00:00 2001 From: Fabian Schuiki Date: Fri, 27 Sep 2024 18:40:54 -0700 Subject: [PATCH] [ImportVerilog] Add support for $clog2 (#7645) Add a `moore.builtin.clog2` op and use it to convert `$clog2` calls in ImportVerilog. --- include/circt/Dialect/Moore/MooreOps.td | 26 ++++++++++++++++++-- lib/Conversion/ImportVerilog/Expressions.cpp | 11 ++++++++- test/Conversion/ImportVerilog/builtins.sv | 16 ++++++++++++ test/Dialect/Moore/basic.mlir | 9 +++++++ 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/include/circt/Dialect/Moore/MooreOps.td b/include/circt/Dialect/Moore/MooreOps.td index d3ec3d106642..ba9096ffc048 100644 --- a/include/circt/Dialect/Moore/MooreOps.td +++ b/include/circt/Dialect/Moore/MooreOps.td @@ -1443,7 +1443,7 @@ class Builtin traits = []> : MooreOp<"builtin." # mnemonic, traits>; //===----------------------------------------------------------------------===// -// Simulation Control +// Simulation Control Builtins //===----------------------------------------------------------------------===// def StopBIOp : Builtin<"stop"> { @@ -1499,7 +1499,7 @@ def FinishMessageBIOp : Builtin<"finish_message"> { } //===----------------------------------------------------------------------===// -// Severity and Display +// Severity and Display Builtins //===----------------------------------------------------------------------===// def DisplayBIOp : Builtin<"display"> { @@ -1544,4 +1544,26 @@ def SeverityBIOp : Builtin<"severity"> { let assemblyFormat = "$severity $message attr-dict"; } +//===----------------------------------------------------------------------===// +// Math Builtins +//===----------------------------------------------------------------------===// + +def Clog2BIOp : Builtin<"clog2", [SameOperandsAndResultType]> { + let summary = "Compute ceil(log2(x)) of x"; + let description = [{ + Computes the ceiling of the base-2 logarithm of the argument. The argument + is interpreted as unsigned. The result is 0 if the argument is 0. The result + corresponds to the minimum address width necessary to address a given number + of elements, or the number of bits necessary to represent a given number of + states. + + If any of the bits in the argument are X or Z, the result is X. + + See IEEE 1800-2017 § 20.8.1 "Integer math functions". + }]; + let arguments = (ins IntType:$value); + let results = (outs IntType:$result); + let assemblyFormat = "$value attr-dict `:` type($value)"; +} + #endif // CIRCT_DIALECT_MOORE_MOOREOPS diff --git a/lib/Conversion/ImportVerilog/Expressions.cpp b/lib/Conversion/ImportVerilog/Expressions.cpp index 2b96d6cc84b2..1eb657118139 100644 --- a/lib/Conversion/ImportVerilog/Expressions.cpp +++ b/lib/Conversion/ImportVerilog/Expressions.cpp @@ -691,9 +691,18 @@ struct RvalueExprVisitor { Value visitCall(const slang::ast::CallExpression &expr, const slang::ast::CallExpression::SystemCallInfo &info) { const auto &subroutine = *info.subroutine; + auto args = expr.arguments(); if (subroutine.name == "$signed" || subroutine.name == "$unsigned") - return context.convertRvalueExpression(*expr.arguments()[0]); + return context.convertRvalueExpression(*args[0]); + + if (subroutine.name == "$clog2") { + auto value = context.convertToSimpleBitVector( + context.convertRvalueExpression(*args[0])); + if (!value) + return {}; + return builder.create(loc, value); + } mlir::emitError(loc) << "unsupported system call `" << subroutine.name << "`"; diff --git a/test/Conversion/ImportVerilog/builtins.sv b/test/Conversion/ImportVerilog/builtins.sv index 5a8b4ab587bc..ae4abbb2d2f2 100644 --- a/test/Conversion/ImportVerilog/builtins.sv +++ b/test/Conversion/ImportVerilog/builtins.sv @@ -5,6 +5,9 @@ // Internal issue in Slang v3 about jump depending on uninitialised value. // UNSUPPORTED: valgrind +function void dummyA(int x); endfunction + +// IEEE 1800-2017 § 20.2 "Simulation control system tasks" // CHECK-LABEL: func.func private @SimulationControlBuiltins( function void SimulationControlBuiltins(bit x); // CHECK: moore.builtin.finish_message false @@ -35,6 +38,8 @@ function void SimulationControlBuiltins(bit x); $exit; endfunction +// IEEE 1800-2017 § 20.10 "Severity tasks" +// IEEE 1800-2017 § 21.2 "Display system tasks" // CHECK-LABEL: func.func private @DisplayAndSeverityBuiltins( // CHECK-SAME: [[X:%.+]]: !moore.i32 function void DisplayAndSeverityBuiltins(int x); @@ -181,3 +186,14 @@ function void DisplayAndSeverityBuiltins(int x); // CHECK: moore.unreachable if (0) $fatal(1, "%d", x); endfunction + +// IEEE 1800-2017 § 20.8 "Math functions" +// CHECK-LABEL: func.func private @MathBuiltins( +// CHECK-SAME: [[X:%.+]]: !moore.i32 +// CHECK-SAME: [[Y:%.+]]: !moore.l42 +function void MathBuiltins(int x, logic [41:0] y); + // CHECK: moore.builtin.clog2 [[X]] : i32 + dummyA($clog2(x)); + // CHECK: moore.builtin.clog2 [[Y]] : l42 + dummyA($clog2(y)); +endfunction diff --git a/test/Dialect/Moore/basic.mlir b/test/Dialect/Moore/basic.mlir index b1ef76ccc9b2..50e674298ebc 100644 --- a/test/Dialect/Moore/basic.mlir +++ b/test/Dialect/Moore/basic.mlir @@ -385,3 +385,12 @@ func.func @SeverityAndDisplayBuiltins(%arg0: !moore.format_string) { moore.builtin.severity fatal %arg0 return } + +// CHECK-LABEL: func.func @MathBuiltins +func.func @MathBuiltins(%arg0: !moore.i32, %arg1: !moore.l42) { + // CHECK: moore.builtin.clog2 %arg0 : i32 + moore.builtin.clog2 %arg0 : i32 + // CHECK: moore.builtin.clog2 %arg1 : l42 + moore.builtin.clog2 %arg1 : l42 + return +}