From f78c356d3699d31983047f3f0326df13d1d32057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Fri, 1 Nov 2024 15:45:46 +0100 Subject: [PATCH] Add `--empty-blackboxes` option --- src/blackboxes.cc | 30 ++++++++++++++++++++++++++++++ src/slang_frontend.cc | 11 +++++++++-- src/slang_frontend.h | 1 + 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/blackboxes.cc b/src/blackboxes.cc index 39900c8..98d329a 100644 --- a/src/blackboxes.cc +++ b/src/blackboxes.cc @@ -170,4 +170,34 @@ void import_blackboxes_from_rtlil(slang::SourceManager &mgr, ast::Compilation &t target.addSyntaxTree(tree); } +bool is_decl_empty_module(const slang::syntax::SyntaxNode &syntax) +{ + using namespace slang::syntax; + + if (syntax.kind != SyntaxKind::ModuleDeclaration) + return false; + + for (auto member : syntax.as().members) { + switch (member->kind) { + case SyntaxKind::TypedefDeclaration: + case SyntaxKind::ForwardTypedefDeclaration: + case SyntaxKind::ParameterDeclaration: + case SyntaxKind::TypeParameterDeclaration: + case SyntaxKind::PortDeclaration: + case SyntaxKind::ImplicitAnsiPort: + case SyntaxKind::ExplicitAnsiPort: + case SyntaxKind::TimeUnitsDeclaration: + case SyntaxKind::FunctionDeclaration: + case SyntaxKind::DefParam: + case SyntaxKind::NetAlias: + break; + + default: + return false; + } + } + + return true; +} + }; diff --git a/src/slang_frontend.cc b/src/slang_frontend.cc index 82b0516..efd613c 100644 --- a/src/slang_frontend.cc +++ b/src/slang_frontend.cc @@ -41,6 +41,7 @@ struct SynthesisSettings { std::optional unroll_limit_; std::optional extern_modules; std::optional no_implicit_memories; + std::optional empty_blackboxes; enum HierMode { NONE, @@ -83,6 +84,8 @@ struct SynthesisSettings { "hierarchy of SystemVerilog and non-SystemVerilog modules"); cmdLine.add("--no-implicit-memories", no_implicit_memories, "Require a memory style attribute to consider a variable for memory inference"); + cmdLine.add("--empty-blackboxes", empty_blackboxes, + "Assume empty modules are blackboxes"); } }; @@ -2455,19 +2458,23 @@ struct PopulateNetlist : public TimingPatternInterpretor, public ast::ASTVisitor } } - static bool has_blackbox_attribute(const ast::DefinitionSymbol &sym) + bool is_blackbox(const ast::DefinitionSymbol &sym) { for (auto attr : sym.getParentScope()->getCompilation().getAttributes(sym)) { if (attr->name == "blackbox"sv && !attr->getValue().isFalse()) return true; } + + if (settings.empty_blackboxes.value_or(false)) + return is_decl_empty_module(*sym.getSyntax()); + return false; } void handle(const ast::InstanceSymbol &sym) { // blackboxes get special handling no matter the hierarchy mode - if (sym.isModule() && has_blackbox_attribute(sym.body.getDefinition())) { + if (sym.isModule() && is_blackbox(sym.body.getDefinition())) { RTLIL::Cell *cell = netlist.canvas->addCell(netlist.id(sym), RTLIL::escape_id(std::string(sym.body.name))); for (auto *conn : sym.getPortConnections()) { diff --git a/src/slang_frontend.h b/src/slang_frontend.h index a0bb2f4..41dded2 100644 --- a/src/slang_frontend.h +++ b/src/slang_frontend.h @@ -207,6 +207,7 @@ extern std::string hierpath_relative_to(const ast::Scope *relative_to, const ast // blackboxes.cc extern void import_blackboxes_from_rtlil(slang::SourceManager &mgr, ast::Compilation &target, RTLIL::Design *source); +extern bool is_decl_empty_module(const slang::syntax::SyntaxNode &syntax); // abort_helpers.cc [[noreturn]] void unimplemented_(const ast::Symbol &obj, const char *file, int line, const char *condition);