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);
78 auto arcContext = AsContextOp::create(builder, loc, instance);
82 auto never = arith::ConstantOp::create(builder, loc,
83 builder.getIntegerAttr(i64Type, -1));
84 auto firstWakeup = GetNextWakeupOp::create(builder, loc, arcContext);
87 scf::WhileOp::create(builder, loc, i64Type, ValueRange{firstWakeup});
91 auto *beforeBlock = builder.createBlock(&whileOp.getBefore());
92 auto wakeup = beforeBlock->addArgument(i64Type, loc);
93 auto pending = arith::CmpIOp::create(builder, loc, arith::CmpIPredicate::ne,
95 scf::ConditionOp::create(builder, loc, pending, ValueRange{wakeup});
99 auto *afterBlock = builder.createBlock(&whileOp.getAfter());
100 auto resumeTime = afterBlock->addArgument(i64Type, loc);
101 SimSetTimeOp::create(builder, loc, instance, resumeTime);
102 SimStepOp::create(builder, loc, instance);
103 auto nextWakeup = GetNextWakeupOp::create(builder, loc, arcContext);
104 scf::YieldOp::create(builder, loc, ValueRange{nextWakeup});
static std::unique_ptr< Context > context
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.