Skip to content

Commit

Permalink
[ImportVerilog]Support real math functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
hailongSun2000 committed Feb 6, 2025
1 parent 3ef66cf commit 92bdfaa
Show file tree
Hide file tree
Showing 3 changed files with 243 additions and 11 deletions.
103 changes: 103 additions & 0 deletions include/circt/Dialect/Moore/MooreOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,23 @@ def StringConstantOp : MooreOp<"string_constant", [Pure]> {
let assemblyFormat = "$value attr-dict `:` type($result)";
}

def RealLiteralOp : MooreOp<"real_constant", [Pure]> {
let summary = "Produce a constant real value";
let description = [{
Produces a constant value of real type.

Example:
```mlir
%0 = moore.real_constant 1.23
```
The real type has fixed-point(1.2) and exponent(2.0e10) formats.
See IEEE 1800-2017 § 5.7.2 "Real literal constants".
}];
let arguments = (ins F64Attr:$value);
let results = (outs RealType:$result);
let assemblyFormat = "$value attr-dict `:` type($result)";
}

//===----------------------------------------------------------------------===//
// Casting and Resizing
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1608,6 +1625,20 @@ def SeverityBIOp : Builtin<"severity"> {
// Math Builtins
//===----------------------------------------------------------------------===//

class RealMathFunc<string mnemonic, list<Trait> traits = []> :
Builtin<mnemonic, traits # [SameOperandsAndResultType]> {
let description = [{
The system real math functions shall accept real value arguments and return
a real result type. Their behavior shall match the equivalent C language
standard math library function indicated.

See IEEE 1800-2017 § 20.8.2 "Real math functions".
}];
let arguments = (ins RealType:$value);
let results = (outs RealType:$result);
let assemblyFormat = "$value attr-dict `:` type($value)";
}

def Clog2BIOp : Builtin<"clog2", [SameOperandsAndResultType]> {
let summary = "Compute ceil(log2(x)) of x";
let description = [{
Expand All @@ -1626,4 +1657,76 @@ def Clog2BIOp : Builtin<"clog2", [SameOperandsAndResultType]> {
let assemblyFormat = "$value attr-dict `:` type($value)";
}

def LnBIOp : RealMathFunc<"ln"> {
let summary = "Natural logarithm";
}

def Log10BIOp : RealMathFunc<"log10"> {
let summary = "Decimal logarithm";
}

def ExpBIOp : RealMathFunc<"exp"> {
let summary = "Exponential";
}

def SqrtBIOp : RealMathFunc<"sqrt"> {
let summary = "Square root";
}

def FloorBIOp : RealMathFunc<"floor"> {
let summary = "Floor";
}

def CeilBIOp : RealMathFunc<"ceil"> {
let summary = "Ceiling";
}

def SinBIOp : RealMathFunc<"sin"> {
let summary = "Sine";
}

def CosBIOp : RealMathFunc<"cos"> {
let summary = "Cosine";
}

def TanBIOp : RealMathFunc<"tan"> {
let summary = "Tangent";
}

def AsinBIOp : RealMathFunc<"asin"> {
let summary = "Arc-sine";
}

def AcosBIOp : RealMathFunc<"acos"> {
let summary = "Arc-cosine";
}

def AtanBIOp : RealMathFunc<"atan"> {
let summary = "Arc-tangent";
}

def SinhBIOp : RealMathFunc<"sinh"> {
let summary = "Hyperbolic sine";
}

def CoshBIOp : RealMathFunc<"cosh"> {
let summary = "Hyperbolic cosine";
}

def TanhBIOp : RealMathFunc<"tanh"> {
let summary = "Hyperbolic tangent";
}

def AsinhBIOp : RealMathFunc<"asinh"> {
let summary = "Arc-hyperbolic sine";
}

def AcoshBIOp : RealMathFunc<"acosh"> {
let summary = "Arc-hyperbolic cosine";
}

def AtanhBIOp : RealMathFunc<"atanh"> {
let summary = "Arc-hyperbolic tangent";
}

#endif // CIRCT_DIALECT_MOORE_MOOREOPS
110 changes: 100 additions & 10 deletions lib/Conversion/ImportVerilog/Expressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -716,17 +716,101 @@ struct RvalueExprVisitor {
const slang::ast::CallExpression::SystemCallInfo &info) {
const auto &subroutine = *info.subroutine;
auto args = expr.arguments();
auto value = context.convertRvalueExpression(*args[0]);
if (!value)
return {};

if (subroutine.name == "$signed" || subroutine.name == "$unsigned")
return context.convertRvalueExpression(*args[0]);

if (subroutine.name == "$clog2") {
auto value = context.convertToSimpleBitVector(
context.convertRvalueExpression(*args[0]));
if (!value)
return {};
return builder.create<moore::Clog2BIOp>(loc, value);
}
auto convertSystemCallArity1 =
llvm::StringSwitch<std::function<Value(Value)>>(subroutine.name)
// Signed and unsigned system functions.
.Case("$signed", [&](Value value) { return value; })
.Case("$unsigned", [&](Value value) { return value; })

// Math functions in SystemVerilog.
.Case("$clog2",
[&](Value value) -> Value {
value = context.convertToSimpleBitVector(value);
if (!value)
return {};
return builder.create<moore::Clog2BIOp>(loc, value);
})
.Case("$ln",
[&](Value value) {
return builder.create<moore::LnBIOp>(loc, value);
})
.Case("$log10",
[&](Value value) {
return builder.create<moore::Log10BIOp>(loc, value);
})
.Case("$sin",
[&](Value value) {
return builder.create<moore::SinBIOp>(loc, value);
})
.Case("$cos",
[&](Value value) {
return builder.create<moore::CosBIOp>(loc, value);
})
.Case("$tan",
[&](Value value) {
return builder.create<moore::TanBIOp>(loc, value);
})
.Case("$exp",
[&](Value value) {
return builder.create<moore::ExpBIOp>(loc, value);
})
.Case("$sqrt",
[&](Value value) {
return builder.create<moore::SqrtBIOp>(loc, value);
})
.Case("$floor",
[&](Value value) {
return builder.create<moore::FloorBIOp>(loc, value);
})
.Case("$ceil",
[&](Value value) {
return builder.create<moore::CeilBIOp>(loc, value);
})
.Case("$asin",
[&](Value value) {
return builder.create<moore::AsinBIOp>(loc, value);
})
.Case("$acos",
[&](Value value) {
return builder.create<moore::AcosBIOp>(loc, value);
})
.Case("$atan",
[&](Value value) {
return builder.create<moore::AtanBIOp>(loc, value);
})
.Case("$sinh",
[&](Value value) {
return builder.create<moore::SinhBIOp>(loc, value);
})
.Case("$cosh",
[&](Value value) {
return builder.create<moore::CoshBIOp>(loc, value);
})
.Case("$tanh",
[&](Value value) {
return builder.create<moore::TanhBIOp>(loc, value);
})
.Case("$asinh",
[&](Value value) {
return builder.create<moore::AsinhBIOp>(loc, value);
})
.Case("$acosh",
[&](Value value) {
return builder.create<moore::AcoshBIOp>(loc, value);
})
.Case("$atanh",
[&](Value value) {
return builder.create<moore::AtanhBIOp>(loc, value);
})
.Default([&](Value value) -> Value { return {}; });

// Invoke realMathFunc() to select which builtin is.
if (auto result = convertSystemCallArity1(value); args.size() == 1)
return result;

mlir::emitError(loc) << "unsupported system call `" << subroutine.name
<< "`";
Expand All @@ -739,6 +823,12 @@ struct RvalueExprVisitor {
return builder.create<moore::StringConstantOp>(loc, type, expr.getValue());
}

/// Handle real literals.
Value visit(const slang::ast::RealLiteral &expr) {
return builder.create<moore::RealLiteralOp>(
loc, builder.getF64FloatAttr(expr.getValue()));
}

/// Handle assignment patterns.
Value visitAssignmentPattern(
const slang::ast::AssignmentPatternExpressionBase &expr,
Expand Down
41 changes: 40 additions & 1 deletion test/Conversion/ImportVerilog/builtins.sv
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// UNSUPPORTED: valgrind

function void dummyA(int x); endfunction
function void dummyB(real x); endfunction

// IEEE 1800-2017 § 20.2 "Simulation control system tasks"
// CHECK-LABEL: func.func private @SimulationControlBuiltins(
Expand Down Expand Up @@ -191,9 +192,47 @@ endfunction
// 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-SAME: [[R:%.+]]: !moore.real
function void MathBuiltins(int x, logic [41:0] y, real r);
// CHECK: moore.builtin.clog2 [[X]] : i32
dummyA($clog2(x));
// CHECK: moore.builtin.clog2 [[Y]] : l42
dummyA($clog2(y));

// CHECK: moore.builtin.ln [[R]] : real
dummyB($ln(r));
// CHECK: moore.builtin.log10 [[R]] : real
dummyB($log10(r));
// CHECK: moore.builtin.exp [[R]] : real
dummyB($exp(r));
// CHECK: moore.builtin.sqrt [[R]] : real
dummyB($sqrt(r));
// CHECK: moore.builtin.floor [[R]] : real
dummyB($floor(r));
// CHECK: moore.builtin.ceil [[R]] : real
dummyB($ceil(r));
// CHECK: moore.builtin.sin [[R]] : real
dummyB($sin(r));
// CHECK: moore.builtin.cos [[R]] : real
dummyB($cos(r));
// CHECK: moore.builtin.tan [[R]] : real
dummyB($tan(r));
// CHECK: moore.builtin.asin [[R]] : real
dummyB($asin(r));
// CHECK: moore.builtin.acos [[R]] : real
dummyB($acos(r));
// CHECK: moore.builtin.atan [[R]] : real
dummyB($atan(r));
// CHECK: moore.builtin.sinh [[R]] : real
dummyB($sinh(r));
// CHECK: moore.builtin.cosh [[R]] : real
dummyB($cosh(r));
// CHECK: moore.builtin.tanh [[R]] : real
dummyB($tanh(r));
// CHECK: moore.builtin.asinh [[R]] : real
dummyB($asinh(r));
// CHECK: moore.builtin.acosh [[R]] : real
dummyB($acosh(r));
// CHECK: moore.builtin.atanh [[R]] : real
dummyB($atanh(r));
endfunction

0 comments on commit 92bdfaa

Please sign in to comment.