From f4211d71ff47729b831434309ca097bccf55534f Mon Sep 17 00:00:00 2001 From: Fabian Schuiki Date: Thu, 10 Oct 2024 14:16:50 -0700 Subject: [PATCH] [MooreToCore] Add support for format strings and display task Lower the format string ops and the `moore.builtin.display` task to the corresponding ops in the Sim dialect. This is not perfect yet, since Sim does not support some of the formatting options. They will be easy to add in the future though. --- include/circt/Conversion/Passes.td | 14 ++-- lib/Conversion/MooreToCore/CMakeLists.txt | 1 + lib/Conversion/MooreToCore/MooreToCore.cpp | 83 ++++++++++++++++++++-- test/Conversion/MooreToCore/basic.mlir | 19 +++++ 4 files changed, 109 insertions(+), 8 deletions(-) diff --git a/include/circt/Conversion/Passes.td b/include/circt/Conversion/Passes.td index 31e224c85b67..dd55af253b80 100644 --- a/include/circt/Conversion/Passes.td +++ b/include/circt/Conversion/Passes.td @@ -512,12 +512,18 @@ def HandshakeToHW : Pass<"lower-handshake-to-hw", "mlir::ModuleOp"> { def ConvertMooreToCore : Pass<"convert-moore-to-core", "mlir::ModuleOp"> { let summary = "Convert Moore to Core"; let description = [{ - This pass translates Moore to the core dialects (Comb/HW/LLHD). + This pass translates Moore to the core dialects. }]; let constructor = "circt::createConvertMooreToCorePass()"; - let dependentDialects = ["comb::CombDialect", "hw::HWDialect", - "llhd::LLHDDialect", "mlir::cf::ControlFlowDialect", - "mlir::scf::SCFDialect", "verif::VerifDialect"]; + let dependentDialects = [ + "comb::CombDialect", + "hw::HWDialect", + "llhd::LLHDDialect", + "mlir::cf::ControlFlowDialect", + "mlir::scf::SCFDialect", + "sim::SimDialect", + "verif::VerifDialect", + ]; } //===----------------------------------------------------------------------===// diff --git a/lib/Conversion/MooreToCore/CMakeLists.txt b/lib/Conversion/MooreToCore/CMakeLists.txt index 999a36e79ddb..fb2f1ed29524 100644 --- a/lib/Conversion/MooreToCore/CMakeLists.txt +++ b/lib/Conversion/MooreToCore/CMakeLists.txt @@ -13,6 +13,7 @@ add_circt_conversion_library(CIRCTMooreToCore CIRCTHW CIRCTLLHD CIRCTMoore + CIRCTSim CIRCTVerif MLIRControlFlowDialect MLIRFuncDialect diff --git a/lib/Conversion/MooreToCore/MooreToCore.cpp b/lib/Conversion/MooreToCore/MooreToCore.cpp index 127edf5a4865..8b1a14540ec6 100644 --- a/lib/Conversion/MooreToCore/MooreToCore.cpp +++ b/lib/Conversion/MooreToCore/MooreToCore.cpp @@ -16,6 +16,7 @@ #include "circt/Dialect/HW/HWOps.h" #include "circt/Dialect/LLHD/IR/LLHDOps.h" #include "circt/Dialect/Moore/MooreOps.h" +#include "circt/Dialect/Sim/SimOps.h" #include "circt/Dialect/Verif/VerifOps.h" #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h" #include "mlir/Dialect/Func/IR/FuncOps.h" @@ -1256,6 +1257,69 @@ struct AssertLikeOpConversion : public OpConversionPattern { } }; +//===----------------------------------------------------------------------===// +// Format String Conversion +//===----------------------------------------------------------------------===// + +struct FormatLiteralOpConversion : public OpConversionPattern { + using OpConversionPattern::OpConversionPattern; + + LogicalResult + matchAndRewrite(FormatLiteralOp op, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + rewriter.replaceOpWithNewOp(op, adaptor.getLiteral()); + return success(); + } +}; + +struct FormatConcatOpConversion : public OpConversionPattern { + using OpConversionPattern::OpConversionPattern; + + LogicalResult + matchAndRewrite(FormatConcatOp op, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + rewriter.replaceOpWithNewOp(op, + adaptor.getInputs()); + return success(); + } +}; + +struct FormatIntOpConversion : public OpConversionPattern { + using OpConversionPattern::OpConversionPattern; + + LogicalResult + matchAndRewrite(FormatIntOp op, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + // TODO: These should honor the width, alignment, and padding. + switch (op.getFormat()) { + case IntFormat::Decimal: + rewriter.replaceOpWithNewOp(op, adaptor.getValue()); + return success(); + case IntFormat::Binary: + rewriter.replaceOpWithNewOp(op, adaptor.getValue()); + return success(); + case IntFormat::HexLower: + case IntFormat::HexUpper: + rewriter.replaceOpWithNewOp(op, adaptor.getValue()); + return success(); + default: + return rewriter.notifyMatchFailure(op, "unsupported int format"); + } + } +}; + +struct DisplayBIOpConversion : public OpConversionPattern { + using OpConversionPattern::OpConversionPattern; + + LogicalResult + matchAndRewrite(DisplayBIOp op, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + rewriter.replaceOpWithNewOp( + op, adaptor.getMessage()); + return success(); + } +}; + } // namespace //===----------------------------------------------------------------------===// @@ -1265,10 +1329,11 @@ struct AssertLikeOpConversion : public OpConversionPattern { static void populateLegality(ConversionTarget &target, const TypeConverter &converter) { target.addIllegalDialect(); - target.addLegalDialect(); + target.addLegalDialect(); target.addLegalDialect(); target.addLegalDialect(); - target.addLegalDialect(); + target.addLegalDialect(); + target.addLegalDialect(); target.addLegalDialect(); target.addLegalOp(); @@ -1295,6 +1360,10 @@ static void populateTypeConversion(TypeConverter &typeConverter) { return IntegerType::get(type.getContext(), type.getWidth()); }); + typeConverter.addConversion([&](FormatStringType type) { + return sim::FormatStringType::get(type.getContext()); + }); + typeConverter.addConversion([&](ArrayType type) -> std::optional { if (auto elementType = typeConverter.convertType(type.getElementType())) return hw::ArrayType::get(elementType, type.getSize()); @@ -1469,12 +1538,18 @@ static void populateOpConversion(RewritePatternSet &patterns, // Patterns of assert-like operations AssertLikeOpConversion, AssertLikeOpConversion, - AssertLikeOpConversion + AssertLikeOpConversion, + + // Format strings. + FormatLiteralOpConversion, + FormatConcatOpConversion, + FormatIntOpConversion, + DisplayBIOpConversion >(typeConverter, context); // clang-format on + mlir::populateAnyFunctionOpInterfaceTypeConversionPattern(patterns, typeConverter); - hw::populateHWModuleLikeTypeConversionPattern( hw::HWModuleOp::getOperationName(), patterns, typeConverter); } diff --git a/test/Conversion/MooreToCore/basic.mlir b/test/Conversion/MooreToCore/basic.mlir index 8a21a601eba9..d76ab40a9d1d 100644 --- a/test/Conversion/MooreToCore/basic.mlir +++ b/test/Conversion/MooreToCore/basic.mlir @@ -320,6 +320,25 @@ func.func @Statements(%arg0: !moore.i42) { return } +// CHECK-LABEL: func @FormatStrings +func.func @FormatStrings(%arg0: !moore.i42) { + // CHECK: [[TMP:%.+]] = sim.fmt.lit "hello" + %0 = moore.fmt.literal "hello" + // CHECK: sim.fmt.concat ([[TMP]], [[TMP]]) + %1 = moore.fmt.concat (%0, %0) + // CHECK: sim.fmt.dec %arg0 : i42 + moore.fmt.int decimal %arg0, width 42, align right, pad space : i42 + // CHECK: sim.fmt.bin %arg0 : i42 + moore.fmt.int binary %arg0, width 42, align right, pad space : i42 + // CHECK: sim.fmt.hex %arg0 : i42 + moore.fmt.int hex_lower %arg0, width 42, align right, pad space : i42 + // CHECK: sim.fmt.hex %arg0 : i42 + moore.fmt.int hex_upper %arg0, width 42, align right, pad space : i42 + // CHECK: sim.proc.print [[TMP]] + moore.builtin.display %0 + return +} + // CHECK-LABEL: hw.module @InstanceNull() { moore.module @InstanceNull() {