51void sv::emitFileDescriptorRuntime(Operation *fileScopeOp,
52 ImplicitLocOpBuilder &builder) {
53 assert(fileScopeOp &&
"expected file-level symbol table op");
54 assert(fileScopeOp->hasTrait<mlir::OpTrait::SymbolTable>() &&
55 "expected fileScopeOp to define a symbol table");
57 OpBuilder::InsertionGuard guard(builder);
58 if (builder.getInsertionBlock() ==
nullptr ||
59 builder.getInsertionBlock()->getParentOp() != fileScopeOp)
60 builder.setInsertionPointToEnd(&fileScopeOp->getRegion(0).front());
62 auto getterSymName = ::getFileDescriptorGetterSymName(builder.getContext());
63 auto fragmentSymName =
64 ::getFileDescriptorFragmentSymName(builder.getContext());
65 auto macroSymName = builder.getStringAttr(kFileDescriptorMacroName);
66 SymbolTable symbolTable(fileScopeOp);
68 auto emitGuard = [&](StringRef guard, llvm::function_ref<void(
void)> body) {
70 builder, guard, [] {}, body);
73 if (!symbolTable.lookup(getterSymName)) {
74 SmallVector<hw::ModulePort> ports;
75 ports.push_back({builder.getStringAttr(
"name"),
76 hw::StringType::get(builder.getContext()),
77 hw::ModulePort::Direction::Input});
78 ports.push_back({builder.getStringAttr(
"fd"), builder.getIntegerType(32),
79 hw::ModulePort::Direction::Output});
81 SmallVector<NamedAttribute> explicitReturnAttrs;
82 explicitReturnAttrs.push_back(
83 {builder.getStringAttr(sv::FuncOp::getExplicitlyReturnedAttrName()),
84 builder.getUnitAttr()});
85 SmallVector<Attribute> perArgumentAttrs = {
86 builder.getDictionaryAttr({}),
87 builder.getDictionaryAttr(explicitReturnAttrs)};
90 sv::FuncOp::create(builder, getterSymName,
91 hw::ModuleType::get(builder.getContext(), ports),
92 builder.getArrayAttr(perArgumentAttrs), ArrayAttr(),
93 ArrayAttr(), getterSymName);
95 symbolTable.insert(func);
98 if (!symbolTable.lookup(macroSymName))
99 symbolTable.insert(sv::MacroDeclOp::create(builder, macroSymName));
101 if (symbolTable.lookup(fragmentSymName))
104 auto fragment = emit::FragmentOp::create(builder, fragmentSymName, [&] {
105 emitGuard(
"SYNTHESIS", [&]() {
106 emitGuard(kFileDescriptorMacroName, [&]() {
107 sv::VerbatimOp::create(builder, R
"(// CIRCT Logging Library
108package __circt_lib_logging;
109 class FileDescriptor;
110 static int global_id [string];
111 static function int get(string name);
112 if (global_id.exists(name) == 32'h0) begin
113 global_id[name] = $fopen(name, "w");
114 if (global_id[name] == 32'h0)
115 $error("Failed to open file %s", name);
117 return global_id[name];
123 sv::MacroDefOp::create(builder, macroSymName, "");
127 symbolTable.insert(fragment);
static std::unique_ptr< Context > context