diff --git a/include/circt/Dialect/LLHD/IR/SignalOps.td b/include/circt/Dialect/LLHD/IR/SignalOps.td index cf55869d072c..7064a317b327 100644 --- a/include/circt/Dialect/LLHD/IR/SignalOps.td +++ b/include/circt/Dialect/LLHD/IR/SignalOps.td @@ -13,7 +13,6 @@ include "mlir/IR/EnumAttr.td" def LLHD_SigOp : LLHD_Op<"sig", [ - ParentOneOf<["llhd::EntityOp", "llhd::ProcOp"]>, TypesMatchWith< "type of 'init' and underlying type of 'signal' have to match.", "init", "result", "SigType::get($_self)"> diff --git a/lib/Conversion/MooreToCore/MooreToCore.cpp b/lib/Conversion/MooreToCore/MooreToCore.cpp index 198329739d54..321bb5337a67 100644 --- a/lib/Conversion/MooreToCore/MooreToCore.cpp +++ b/lib/Conversion/MooreToCore/MooreToCore.cpp @@ -144,6 +144,31 @@ struct InstanceOpConversion : public OpConversionPattern { } }; +//===----------------------------------------------------------------------===// +// Declaration Conversion +//===----------------------------------------------------------------------===// + +struct VariableOpConversion : public OpConversionPattern { + using OpConversionPattern::OpConversionPattern; + + LogicalResult + matchAndRewrite(VariableOp op, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + Type resultType = typeConverter->convertType(op.getResult().getType()); + Value init = adaptor.getInitial(); + // TODO: Unsupport x/z, so the initial value is 0. + if (!init && cast(op.getResult().getType()).getDomain() == + Domain::FourValued) + return failure(); + + if (!init) + init = rewriter.create(op->getLoc(), resultType, 0); + rewriter.replaceOpWithNewOp(op, llhd::SigType::get(resultType), + op.getName(), init); + return success(); + } +}; + //===----------------------------------------------------------------------===// // Expression Conversion //===----------------------------------------------------------------------===// @@ -511,6 +536,39 @@ struct AShrOpConversion : public OpConversionPattern { } }; +struct ReadOpConversion : public OpConversionPattern { + using OpConversionPattern::OpConversionPattern; + + LogicalResult + matchAndRewrite(ReadOp op, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + Type resultType = typeConverter->convertType(op.getResult().getType()); + rewriter.replaceOpWithNewOp(op, resultType, + adaptor.getInput()); + return success(); + } +}; + +template +struct AssignOpConversion : public OpConversionPattern { + using OpConversionPattern::OpConversionPattern; + using OpAdaptor = typename OpTy::Adaptor; + + LogicalResult + matchAndRewrite(OpTy op, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + // TODO: When we support delay control in Moore dialect, we need to update + // this conversion. + auto timeAttr = + llhd::TimeAttr::get(op->getContext(), unsigned(0), + llvm::StringRef("ns"), unsigned(0), unsigned(0)); + auto time = rewriter.create(op->getLoc(), timeAttr); + rewriter.replaceOpWithNewOp(op, adaptor.getDst(), + adaptor.getSrc(), time, Value{}); + return success(); + } +}; + } // namespace //===----------------------------------------------------------------------===// @@ -574,6 +632,13 @@ static void populateTypeConversion(TypeConverter &typeConverter) { return mlir::IntegerType::get(type.getContext(), type.getWidth()); }); + typeConverter.addConversion([&](RefType type) -> std::optional { + if (isa(type.getNestedType())) + return mlir::IntegerType::get(type.getContext(), + type.getBitSize().value()); + return std::nullopt; + }); + // Valid target types. typeConverter.addConversion([](mlir::IntegerType type) { return type; }); typeConverter.addTargetMaterialization( @@ -600,9 +665,12 @@ static void populateOpConversion(RewritePatternSet &patterns, auto *context = patterns.getContext(); // clang-format off patterns.add< + // Patterns of declaration operations. + VariableOpConversion, + // Patterns of miscellaneous operations. ConstantOpConv, ConcatOpConversion, ReplicateOpConversion, - ExtractOpConversion, ConversionOpConversion, + ExtractOpConversion, ConversionOpConversion, ReadOpConversion, NamedConstantOpConv, // Patterns of unary operations. @@ -643,6 +711,9 @@ static void populateOpConversion(RewritePatternSet &patterns, // Patterns of shifting operations. ShrOpConversion, ShlOpConversion, AShrOpConversion, + // Patterns of assignment operations. + AssignOpConversion, + // Patterns of branch operations. CondBranchOpConversion, BranchOpConversion, diff --git a/test/Conversion/MooreToCore/basic.mlir b/test/Conversion/MooreToCore/basic.mlir index a572c9223980..17507e1e7b9e 100644 --- a/test/Conversion/MooreToCore/basic.mlir +++ b/test/Conversion/MooreToCore/basic.mlir @@ -254,3 +254,35 @@ moore.module @ParamTest(){ %2 = moore.constant 3 : l32 %sp1 = moore.named_constant specparam %2 : l32 } + +moore.module @Variable() { + // CHECK: [[TMP0:%.+]] = hw.constant 0 : i32 + // CHECK: [[A:%.+]] = llhd.sig "a" [[TMP0]] : i32 + %a = moore.variable : + + // CHECK: [[TMP1:%.+]] = hw.constant 0 : i8 + // CHECK: [[B:%.+]] = llhd.sig "b1" [[TMP1]] : i8 + %b1 = moore.variable : + + // CHECK: [[PRB:%.+]] = llhd.prb [[B]] : !llhd.sig + %0 = moore.read %b1 : i8 + // CHECK: llhd.sig "b2" [[PRB]] : i8 + %b2 = moore.variable %0 : + + // CHECK: %true = hw.constant true + %1 = moore.constant true : i1 + // CHECK: [[CAST:%.+]] = hw.bitcast %true : (i1) -> i1 + %2 = moore.conversion %1 : !moore.i1 -> !moore.l1 + // CHECK: llhd.sig "l" [[CAST]] : i1 + %l = moore.variable %2 : + + // CHECK: [[TMP2:%.+]] = hw.constant 10 : i32 + %3 = moore.constant 10 : i32 + + // CHECK: [[TIME:%.+]] = llhd.constant_time <0ns, 0d, 0e> + // CHECK: llhd.drv [[A]], [[TMP2]] after [[TIME]] : !llhd.sig + moore.assign %a, %3 : i32 + + // CHECK: hw.output + moore.output +} diff --git a/test/Dialect/LLHD/IR/signal-errors.mlir b/test/Dialect/LLHD/IR/signal-errors.mlir index 94a75a448aa3..4d141f1a72e4 100644 --- a/test/Dialect/LLHD/IR/signal-errors.mlir +++ b/test/Dialect/LLHD/IR/signal-errors.mlir @@ -40,10 +40,3 @@ llhd.entity @check_unique_sig_names2 () -> () { %sig1 = llhd.sig "sigI1" %cI1 : i1 %sig2 = llhd.output "sigI1" %cI1 after %time : i1 } - -// ----- - -func.func @illegal_sig_parent (%arg0: i1) { - // expected-error @+1 {{expects parent op to be one of 'llhd.entity, llhd.proc'}} - %0 = llhd.sig "sig" %arg0 : i1 -}