18#include "mlir/Dialect/Arith/IR/Arith.h"
19#include "mlir/Dialect/Func/IR/FuncOps.h"
20#include "mlir/Dialect/SCF/IR/SCF.h"
21#include "mlir/IR/SymbolTable.h"
22#include "mlir/Pass/Pass.h"
26#define GEN_PASS_DEF_GENERATEDRIVER
27#include "circt/Dialect/Arc/ArcPasses.h.inc"
40struct GenerateDriverPass
41 :
public arc::impl::GenerateDriverBase<GenerateDriverPass> {
42 void runOnOperation()
override;
43 void generateDriver(ModelOp modelOp, SymbolTable &symbolTable);
47void GenerateDriverPass::runOnOperation() {
48 auto &symbolTable = getAnalysis<SymbolTable>();
49 for (
auto modelOp : getOperation().getOps<ModelOp>())
50 generateDriver(modelOp, symbolTable);
55void GenerateDriverPass::generateDriver(ModelOp modelOp,
56 SymbolTable &symbolTable) {
58 auto loc = modelOp.getLoc();
59 auto i64Type = IntegerType::get(
context, 64);
60 auto instanceType = SimModelInstanceType::get(
61 context, FlatSymbolRefAttr::get(modelOp.getSymNameAttr()));
65 OpBuilder builder(modelOp);
66 auto funcName = builder.getStringAttr(modelOp.getSymName() +
"_main");
67 auto funcType = builder.getFunctionType({}, {});
68 auto funcOp = func::FuncOp::create(builder, loc, funcName, funcType);
69 symbolTable.insert(funcOp);
70 builder.setInsertionPointToStart(funcOp.addEntryBlock());
74 auto instanceOp = SimInstantiateOp::create(builder, loc);
75 func::ReturnOp::create(builder, loc);
76 auto *instanceBlock = builder.createBlock(&instanceOp.getBody());
77 auto instance = instanceBlock->addArgument(instanceType, loc);
81 auto never = arith::ConstantOp::create(builder, loc,
82 builder.getIntegerAttr(i64Type, -1));
83 auto firstWakeup = SimGetNextWakeupOp::create(builder, loc, instance);
86 scf::WhileOp::create(builder, loc, i64Type, ValueRange{firstWakeup});
90 auto *beforeBlock = builder.createBlock(&whileOp.getBefore());
91 auto wakeup = beforeBlock->addArgument(i64Type, loc);
92 auto pending = arith::CmpIOp::create(builder, loc, arith::CmpIPredicate::ne,
94 scf::ConditionOp::create(builder, loc, pending, ValueRange{wakeup});
98 auto *afterBlock = builder.createBlock(&whileOp.getAfter());
99 auto resumeTime = afterBlock->addArgument(i64Type, loc);
100 SimSetTimeOp::create(builder, loc, instance, resumeTime);
101 SimStepOp::create(builder, loc, instance);
102 auto nextWakeup = SimGetNextWakeupOp::create(builder, loc, instance);
103 scf::YieldOp::create(builder, loc, ValueRange{nextWakeup});
static std::unique_ptr< Context > context
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.