17 #include "mlir/Pass/Pass.h"
18 #include "mlir/Transforms/DialectConversion.h"
21 using namespace circt;
30 class InteropVerilatedOpConversion
36 matchAndRewrite(InteropVerilatedOp op, OpAdaptor adaptor,
37 ConversionPatternRewriter &rewriter)
const override {
42 SmallString<128> verilatedModuleName(
"V");
43 verilatedModuleName += op.getModuleName();
46 Location loc = op.getLoc();
51 SymbolTable::lookupNearestSymbolFrom(op, op.getModuleNameAttr());
52 OpBuilder includeBuilder(hwModule);
53 includeBuilder.create<emitc::IncludeOp>(
54 loc, (verilatedModuleName +
".h").str(),
false);
57 Value state = rewriter
58 .create<interop::ProceduralAllocOp>(loc, stateType,
59 InteropMechanism::CPP)
62 insertStateInitialization(rewriter, loc, state);
64 ValueRange results = insertUpdateLogic(
65 rewriter, loc, state, adaptor.getInputs(), op.getResults(),
66 adaptor.getInputNames(), adaptor.getResultNames());
68 insertStateDeallocation(rewriter, loc, state);
72 rewriter.replaceOp(op, results);
79 void insertStateInitialization(PatternRewriter &rewriter, Location loc,
81 auto initOp = rewriter.create<interop::ProceduralInitOp>(
82 loc, state, InteropMechanism::CPP);
84 OpBuilder initBuilder = OpBuilder::atBlockBegin(initOp.getBody());
86 initBuilder.create<NewOp>(loc, state.getType(), ValueRange());
87 initBuilder.create<interop::ReturnOp>(loc, newState);
93 ValueRange insertUpdateLogic(PatternRewriter &rewriter, Location loc,
94 Value stateValue, ValueRange inputValues,
95 ValueRange resultValues, ArrayAttr inputNames,
96 ArrayAttr resultNames)
const {
97 auto updateOp = rewriter.create<interop::ProceduralUpdateOp>(
98 loc, resultValues.getTypes(), inputValues, stateValue,
99 InteropMechanism::CPP);
101 OpBuilder updateBuilder = OpBuilder::atBlockBegin(updateOp.getBody());
104 Value state = updateOp.getBody()->getArguments().front();
105 for (
size_t i = 0; i < inputValues.size(); ++i) {
106 Value member = updateBuilder.create<MemberAccessOp>(
107 loc, inputValues[i].getType(), state, cast<StringAttr>(inputNames[i]),
108 MemberAccessKind::Arrow);
109 updateBuilder.create<AssignOp>(loc, member,
110 updateOp.getBody()->getArgument(i + 1));
114 auto evalFunc = updateBuilder.create<MemberAccessOp>(
116 "eval", MemberAccessKind::Arrow);
121 updateBuilder.create<func::CallIndirectOp>(loc, evalFunc.getResult());
124 SmallVector<Value> results;
125 for (
size_t i = 0; i < resultValues.size(); ++i) {
126 results.push_back(updateBuilder.create<MemberAccessOp>(
127 loc, resultValues[i].getType(), state,
128 cast<StringAttr>(resultNames[i]).getValue(),
129 MemberAccessKind::Arrow));
132 updateBuilder.create<interop::ReturnOp>(loc, results);
134 return updateOp->getResults();
138 void insertStateDeallocation(PatternRewriter &rewriter, Location loc,
140 auto deallocOp = rewriter.create<interop::ProceduralDeallocOp>(
141 loc, state, InteropMechanism::CPP);
143 OpBuilder deallocBuilder = OpBuilder::atBlockBegin(deallocOp.getBody());
144 deallocBuilder.create<DeleteOp>(loc, deallocOp.getBody()->getArgument(0));
154 struct SystemCLowerInstanceInteropPass
155 : SystemCLowerInstanceInteropBase<SystemCLowerInstanceInteropPass> {
156 void runOnOperation()
override;
161 RewritePatternSet &
patterns, MLIRContext *ctx) {
162 patterns.add<InteropVerilatedOpConversion>(ctx);
165 void SystemCLowerInstanceInteropPass::runOnOperation() {
166 RewritePatternSet
patterns(&getContext());
168 ConversionTarget target(getContext());
169 target.addLegalDialect<interop::InteropDialect>();
170 target.addLegalDialect<emitc::EmitCDialect>();
171 target.addLegalDialect<SystemCDialect>();
172 target.addLegalOp<func::CallIndirectOp>();
173 target.addIllegalOp<InteropVerilatedOp>();
180 applyPartialConversion(getOperation(), target, std::move(
patterns))))
186 return std::make_unique<SystemCLowerInstanceInteropPass>();
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
std::unique_ptr< mlir::Pass > createSystemCLowerInstanceInteropPass()
Create the SystemC Lower Interop pass.
void populateSystemCLowerInstanceInteropPatterns(mlir::RewritePatternSet &patterns, mlir::MLIRContext *ctx)
Populate the rewrite patterns for SystemC's instance-side interop lowerings.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.