Skip to content

[ImportVerilog][MooreToCore] Adds support for System Verilog real maths functions#10746

Open
jpkirs wants to merge 6 commits into
llvm:mainfrom
hm-aemy:dev/jpk/issue_8930
Open

[ImportVerilog][MooreToCore] Adds support for System Verilog real maths functions#10746
jpkirs wants to merge 6 commits into
llvm:mainfrom
hm-aemy:dev/jpk/issue_8930

Conversation

@jpkirs

@jpkirs jpkirs commented Jun 30, 2026

Copy link
Copy Markdown

This commit adds support for the System Verilog real math functions (IEEE1800-2017 Chapter 20.8) by adding previously missing patterns for conversion from Verilog to the 'moore' dialect and adds patterns for conversion using the MLIR dialects 'arith' and 'math' to allow the use of the real math functions as non-synthesizable constructs.

In combination with adding explicit conversion between int and real from the pull requests #9088 and #9317 this addresses the issue using the math functions as raised in issue #8930.

This is done by adding:

  • A class RealMathFuncTwoIn in include/circt/Dialect/Moore/MooreOps.td for real math functions with two operants.
  • A template convertRealMathTwoBI in lib/Conversion/ImportVerilog/Expressions.cpp for real math functions with two operants that can converted into a single operation in the 'arith' or 'math' dialect.
  • A struct Clog2BIOpConversion in lib/Conversion/MooreToCore/MooreToCore.cpp for conversion of the clog2 function from 'moore' a 'math' and 'arith' representation.
  • A struct RealMathFunc and a struct RealMathFuncTwoArg in lib/Conversion/MooreToCore/MooreToCore.cpp for conversion of real math functions into the 'math' and 'arith' dialects.
  • A struct HypotBIOpConversion and a struct RealMathFuncTwoArg in lib/Conversion/MooreToCore/MooreToCore.cpp for conversion of the hypot-function the 'math' and 'arith' dialects.
  • Tests for the import of real math functions with two arguments in test/Conversion/ImportVerilog/builtins.sv.
  • Tests for conversion to core dialects of real math functions in test/Conversion/MooreToCore/basic.mlir.
  • Tests for real math functions in 'moore' dialect in test/Dialect/Moore/basic.mlir.

@fabianschuiki fabianschuiki left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really cool, thanks a lot for tackling these @jpkirs. Just a small nit about an accidental deletion in the code -- will probably break CI.

Comment on lines -3251 to -3278
static LogicalResult
emitScanAssignments(Context &context, const Context::ScanStringResult &result,
Location loc) {
auto &builder = context.builder;
auto newBlockAfter = [&](Block *after) -> Block * {
auto block = std::make_unique<Block>();
block->insertAfter(after);
return block.release();
};

for (auto [destExpr, value, matched] : result.assignments) {
auto lhs = context.convertLvalueExpression(*destExpr);
if (!lhs)
return failure();
auto cond = moore::ToBuiltinIntOp::create(builder, loc, matched);

auto *assignBlock = newBlockAfter(builder.getInsertionBlock());
auto *continuedBlock = newBlockAfter(assignBlock);
mlir::cf::CondBranchOp::create(builder, loc, cond, assignBlock,
continuedBlock);

builder.setInsertionPointToEnd(assignBlock);
moore::BlockingAssignOp::create(builder, loc, lhs, value);
mlir::cf::BranchOp::create(builder, loc, continuedBlock);

builder.setInsertionPointToEnd(continuedBlock);
}
return success();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: looks like an accidental deletion or rebase mishap.

Comment on lines +1799 to +1821
struct Clog2BIOpConversion : public OpConversionPattern<Clog2BIOp> {
using OpConversionPattern::OpConversionPattern;
LogicalResult
matchAndRewrite(Clog2BIOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
Value ceil_log;
auto len_in = adaptor.getValue().getType().getIntOrFloatBitWidth();
auto tofloat = arith::UIToFPOp::create(
rewriter, op.getLoc(), rewriter.getF32Type(), adaptor.getValue());
if (tofloat == 0) {
ceil_log = 0;
} else {
ceil_log = math::CeilOp::create(
rewriter, op.getLoc(),
math::Log2Op::create(rewriter, op.getLoc(), tofloat));
}
Value out = arith::FPToUIOp::create(
rewriter, op.getLoc(), rewriter.getIntegerType(len_in), ceil_log);
rewriter.replaceOp(op, out);
return success();
}
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the Arith dialect have some flavor of leading zero counting, such that we could implement this purely as an integer operation instead of casting to floats?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants