Skip to content

Commit 2b25325

Browse files
Hailong Sunfabianschuikichenbo-again
authored
[ImportVerilog]Support real math functions. (#8192)
Co-authored-by: Fabian Schuiki <[email protected]> Co-authored-by: chenbo <[email protected]>
1 parent 39f7d01 commit 2b25325

File tree

4 files changed

+254
-8
lines changed

4 files changed

+254
-8
lines changed

include/circt/Dialect/Moore/MooreOps.td

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,23 @@ def StringConstantOp : MooreOp<"string_constant", [Pure]> {
508508
let assemblyFormat = "$value attr-dict `:` type($result)";
509509
}
510510

511+
def RealLiteralOp : MooreOp<"real_constant", [Pure]> {
512+
let summary = "Produce a constant real value";
513+
let description = [{
514+
Produces a constant value of real type.
515+
516+
Example:
517+
```mlir
518+
%0 = moore.real_constant 1.23
519+
```
520+
The real type has fixed-point(1.2) and exponent(2.0e10) formats.
521+
See IEEE 1800-2017 § 5.7.2 "Real literal constants".
522+
}];
523+
let arguments = (ins F64Attr:$value);
524+
let results = (outs RealType:$result);
525+
let assemblyFormat = "$value attr-dict `:` type($result)";
526+
}
527+
511528
//===----------------------------------------------------------------------===//
512529
// Casting and Resizing
513530
//===----------------------------------------------------------------------===//
@@ -1610,6 +1627,20 @@ def SeverityBIOp : Builtin<"severity"> {
16101627
// Math Builtins
16111628
//===----------------------------------------------------------------------===//
16121629

1630+
class RealMathFunc<string mnemonic, list<Trait> traits = []> :
1631+
Builtin<mnemonic, traits # [SameOperandsAndResultType]> {
1632+
let description = [{
1633+
The system real math functions shall accept real value arguments and return
1634+
a real result type. Their behavior shall match the equivalent C language
1635+
standard math library function indicated.
1636+
1637+
See IEEE 1800-2017 § 20.8.2 "Real math functions".
1638+
}];
1639+
let arguments = (ins RealType:$value);
1640+
let results = (outs RealType:$result);
1641+
let assemblyFormat = "$value attr-dict `:` type($value)";
1642+
}
1643+
16131644
def Clog2BIOp : Builtin<"clog2", [SameOperandsAndResultType]> {
16141645
let summary = "Compute ceil(log2(x)) of x";
16151646
let description = [{
@@ -1628,4 +1659,76 @@ def Clog2BIOp : Builtin<"clog2", [SameOperandsAndResultType]> {
16281659
let assemblyFormat = "$value attr-dict `:` type($value)";
16291660
}
16301661

1662+
def LnBIOp : RealMathFunc<"ln"> {
1663+
let summary = "Natural logarithm";
1664+
}
1665+
1666+
def Log10BIOp : RealMathFunc<"log10"> {
1667+
let summary = "Decimal logarithm";
1668+
}
1669+
1670+
def ExpBIOp : RealMathFunc<"exp"> {
1671+
let summary = "Exponential";
1672+
}
1673+
1674+
def SqrtBIOp : RealMathFunc<"sqrt"> {
1675+
let summary = "Square root";
1676+
}
1677+
1678+
def FloorBIOp : RealMathFunc<"floor"> {
1679+
let summary = "Floor";
1680+
}
1681+
1682+
def CeilBIOp : RealMathFunc<"ceil"> {
1683+
let summary = "Ceiling";
1684+
}
1685+
1686+
def SinBIOp : RealMathFunc<"sin"> {
1687+
let summary = "Sine";
1688+
}
1689+
1690+
def CosBIOp : RealMathFunc<"cos"> {
1691+
let summary = "Cosine";
1692+
}
1693+
1694+
def TanBIOp : RealMathFunc<"tan"> {
1695+
let summary = "Tangent";
1696+
}
1697+
1698+
def AsinBIOp : RealMathFunc<"asin"> {
1699+
let summary = "Arc-sine";
1700+
}
1701+
1702+
def AcosBIOp : RealMathFunc<"acos"> {
1703+
let summary = "Arc-cosine";
1704+
}
1705+
1706+
def AtanBIOp : RealMathFunc<"atan"> {
1707+
let summary = "Arc-tangent";
1708+
}
1709+
1710+
def SinhBIOp : RealMathFunc<"sinh"> {
1711+
let summary = "Hyperbolic sine";
1712+
}
1713+
1714+
def CoshBIOp : RealMathFunc<"cosh"> {
1715+
let summary = "Hyperbolic cosine";
1716+
}
1717+
1718+
def TanhBIOp : RealMathFunc<"tanh"> {
1719+
let summary = "Hyperbolic tangent";
1720+
}
1721+
1722+
def AsinhBIOp : RealMathFunc<"asinh"> {
1723+
let summary = "Arc-hyperbolic sine";
1724+
}
1725+
1726+
def AcoshBIOp : RealMathFunc<"acosh"> {
1727+
let summary = "Arc-hyperbolic cosine";
1728+
}
1729+
1730+
def AtanhBIOp : RealMathFunc<"atanh"> {
1731+
let summary = "Arc-hyperbolic tangent";
1732+
}
1733+
16311734
#endif // CIRCT_DIALECT_MOORE_MOOREOPS

lib/Conversion/ImportVerilog/Expressions.cpp

Lines changed: 106 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -751,15 +751,15 @@ struct RvalueExprVisitor {
751751
const auto &subroutine = *info.subroutine;
752752
auto args = expr.arguments();
753753

754-
if (subroutine.name == "$signed" || subroutine.name == "$unsigned")
755-
return context.convertRvalueExpression(*args[0]);
756-
757-
if (subroutine.name == "$clog2") {
758-
auto value = context.convertToSimpleBitVector(
759-
context.convertRvalueExpression(*args[0]));
754+
if (args.size() == 1) {
755+
auto value = context.convertRvalueExpression(*args[0]);
760756
if (!value)
761757
return {};
762-
return builder.create<moore::Clog2BIOp>(loc, value);
758+
auto result = context.convertSystemCallArity1(subroutine, loc, value);
759+
if (failed(result))
760+
return {};
761+
if (*result)
762+
return *result;
763763
}
764764

765765
mlir::emitError(loc) << "unsupported system call `" << subroutine.name
@@ -773,6 +773,12 @@ struct RvalueExprVisitor {
773773
return builder.create<moore::StringConstantOp>(loc, type, expr.getValue());
774774
}
775775

776+
/// Handle real literals.
777+
Value visit(const slang::ast::RealLiteral &expr) {
778+
return builder.create<moore::RealLiteralOp>(
779+
loc, builder.getF64FloatAttr(expr.getValue()));
780+
}
781+
776782
/// Handle assignment patterns.
777783
Value visitAssignmentPattern(
778784
const slang::ast::AssignmentPatternExpressionBase &expr,
@@ -1310,3 +1316,96 @@ Value Context::materializeConversion(Type type, Value value, bool isSigned,
13101316
value = builder.create<moore::ConversionOp>(loc, type, value);
13111317
return value;
13121318
}
1319+
1320+
FailureOr<Value>
1321+
Context::convertSystemCallArity1(const slang::ast::SystemSubroutine &subroutine,
1322+
Location loc, Value value) {
1323+
auto systemCallRes =
1324+
llvm::StringSwitch<std::function<FailureOr<Value>()>>(subroutine.name)
1325+
// Signed and unsigned system functions.
1326+
.Case("$signed", [&]() { return value; })
1327+
.Case("$unsigned", [&]() { return value; })
1328+
1329+
// Math functions in SystemVerilog.
1330+
.Case("$clog2",
1331+
[&]() -> FailureOr<Value> {
1332+
value = convertToSimpleBitVector(value);
1333+
if (!value)
1334+
return failure();
1335+
return (Value)builder.create<moore::Clog2BIOp>(loc, value);
1336+
})
1337+
.Case("$ln",
1338+
[&]() -> Value {
1339+
return builder.create<moore::LnBIOp>(loc, value);
1340+
})
1341+
.Case("$log10",
1342+
[&]() -> Value {
1343+
return builder.create<moore::Log10BIOp>(loc, value);
1344+
})
1345+
.Case("$sin",
1346+
[&]() -> Value {
1347+
return builder.create<moore::SinBIOp>(loc, value);
1348+
})
1349+
.Case("$cos",
1350+
[&]() -> Value {
1351+
return builder.create<moore::CosBIOp>(loc, value);
1352+
})
1353+
.Case("$tan",
1354+
[&]() -> Value {
1355+
return builder.create<moore::TanBIOp>(loc, value);
1356+
})
1357+
.Case("$exp",
1358+
[&]() -> Value {
1359+
return builder.create<moore::ExpBIOp>(loc, value);
1360+
})
1361+
.Case("$sqrt",
1362+
[&]() -> Value {
1363+
return builder.create<moore::SqrtBIOp>(loc, value);
1364+
})
1365+
.Case("$floor",
1366+
[&]() -> Value {
1367+
return builder.create<moore::FloorBIOp>(loc, value);
1368+
})
1369+
.Case("$ceil",
1370+
[&]() -> Value {
1371+
return builder.create<moore::CeilBIOp>(loc, value);
1372+
})
1373+
.Case("$asin",
1374+
[&]() -> Value {
1375+
return builder.create<moore::AsinBIOp>(loc, value);
1376+
})
1377+
.Case("$acos",
1378+
[&]() -> Value {
1379+
return builder.create<moore::AcosBIOp>(loc, value);
1380+
})
1381+
.Case("$atan",
1382+
[&]() -> Value {
1383+
return builder.create<moore::AtanBIOp>(loc, value);
1384+
})
1385+
.Case("$sinh",
1386+
[&]() -> Value {
1387+
return builder.create<moore::SinhBIOp>(loc, value);
1388+
})
1389+
.Case("$cosh",
1390+
[&]() -> Value {
1391+
return builder.create<moore::CoshBIOp>(loc, value);
1392+
})
1393+
.Case("$tanh",
1394+
[&]() -> Value {
1395+
return builder.create<moore::TanhBIOp>(loc, value);
1396+
})
1397+
.Case("$asinh",
1398+
[&]() -> Value {
1399+
return builder.create<moore::AsinhBIOp>(loc, value);
1400+
})
1401+
.Case("$acosh",
1402+
[&]() -> Value {
1403+
return builder.create<moore::AcoshBIOp>(loc, value);
1404+
})
1405+
.Case("$atanh",
1406+
[&]() -> Value {
1407+
return builder.create<moore::AtanhBIOp>(loc, value);
1408+
})
1409+
.Default([&]() -> Value { return {}; });
1410+
return systemCallRes();
1411+
}

lib/Conversion/ImportVerilog/ImportVerilogInternals.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ struct Context {
163163
moore::IntFormat defaultFormat = moore::IntFormat::Decimal,
164164
bool appendNewline = false);
165165

166+
/// Convert system function calls only have arity-1.
167+
FailureOr<Value>
168+
convertSystemCallArity1(const slang::ast::SystemSubroutine &subroutine,
169+
Location loc, Value value);
170+
166171
/// Evaluate the constant value of an expression.
167172
slang::ConstantValue evaluateConstant(const slang::ast::Expression &expr);
168173

test/Conversion/ImportVerilog/builtins.sv

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// UNSUPPORTED: valgrind
77

88
function void dummyA(int x); endfunction
9+
function void dummyB(real x); endfunction
910

1011
// IEEE 1800-2017 § 20.2 "Simulation control system tasks"
1112
// CHECK-LABEL: func.func private @SimulationControlBuiltins(
@@ -191,9 +192,47 @@ endfunction
191192
// CHECK-LABEL: func.func private @MathBuiltins(
192193
// CHECK-SAME: [[X:%.+]]: !moore.i32
193194
// CHECK-SAME: [[Y:%.+]]: !moore.l42
194-
function void MathBuiltins(int x, logic [41:0] y);
195+
// CHECK-SAME: [[R:%.+]]: !moore.real
196+
function void MathBuiltins(int x, logic [41:0] y, real r);
195197
// CHECK: moore.builtin.clog2 [[X]] : i32
196198
dummyA($clog2(x));
197199
// CHECK: moore.builtin.clog2 [[Y]] : l42
198200
dummyA($clog2(y));
201+
202+
// CHECK: moore.builtin.ln [[R]] : real
203+
dummyB($ln(r));
204+
// CHECK: moore.builtin.log10 [[R]] : real
205+
dummyB($log10(r));
206+
// CHECK: moore.builtin.exp [[R]] : real
207+
dummyB($exp(r));
208+
// CHECK: moore.builtin.sqrt [[R]] : real
209+
dummyB($sqrt(r));
210+
// CHECK: moore.builtin.floor [[R]] : real
211+
dummyB($floor(r));
212+
// CHECK: moore.builtin.ceil [[R]] : real
213+
dummyB($ceil(r));
214+
// CHECK: moore.builtin.sin [[R]] : real
215+
dummyB($sin(r));
216+
// CHECK: moore.builtin.cos [[R]] : real
217+
dummyB($cos(r));
218+
// CHECK: moore.builtin.tan [[R]] : real
219+
dummyB($tan(r));
220+
// CHECK: moore.builtin.asin [[R]] : real
221+
dummyB($asin(r));
222+
// CHECK: moore.builtin.acos [[R]] : real
223+
dummyB($acos(r));
224+
// CHECK: moore.builtin.atan [[R]] : real
225+
dummyB($atan(r));
226+
// CHECK: moore.builtin.sinh [[R]] : real
227+
dummyB($sinh(r));
228+
// CHECK: moore.builtin.cosh [[R]] : real
229+
dummyB($cosh(r));
230+
// CHECK: moore.builtin.tanh [[R]] : real
231+
dummyB($tanh(r));
232+
// CHECK: moore.builtin.asinh [[R]] : real
233+
dummyB($asinh(r));
234+
// CHECK: moore.builtin.acosh [[R]] : real
235+
dummyB($acosh(r));
236+
// CHECK: moore.builtin.atanh [[R]] : real
237+
dummyB($atanh(r));
199238
endfunction

0 commit comments

Comments
 (0)