diff --git a/src/V3Config.cpp b/src/V3Config.cpp index 91482d6a1..f245cf9aa 100644 --- a/src/V3Config.cpp +++ b/src/V3Config.cpp @@ -532,6 +532,18 @@ public: //###################################################################### // Resolve modules and files in the design +class V3ConfigResolverHierWorkerEntry final { + const int m_workers; + FileLine* const m_flp; + +public: + explicit V3ConfigResolverHierWorkerEntry(int workers, FileLine* flp) + : m_workers{workers} + , m_flp{flp} {} + int workers() const { return m_workers; } + FileLine* flp() const { return m_flp; } +}; + class V3ConfigResolver final { enum ProfileDataMode : uint8_t { NONE = 0, MTASK = 1, HIER_DPI = 2 }; V3ConfigModuleResolver m_modules; // Access to module names (with wildcards) @@ -540,8 +552,7 @@ class V3ConfigResolver final { std::unordered_map> m_profileData; // Access to profile_data records uint8_t m_mode = NONE; - std::unordered_map m_hierWorkers; - FileLine* m_hierWorkersFileLine = nullptr; + std::unordered_map m_hierWorkers; FileLine* m_profileFileLine = nullptr; V3ConfigResolver() = default; @@ -572,16 +583,19 @@ public: // Empty key for hierarchical DPI wrapper costs. return getProfileData(hierDpi, ""); } - void addHierWorkers(FileLine* fl, const string& model, int workers) { - if (!m_hierWorkersFileLine) m_hierWorkersFileLine = fl; - m_hierWorkers[model] = workers; + void addHierWorkers(FileLine* flp, const string& model, int workers) { + m_hierWorkers.emplace(std::piecewise_construct, std::forward_as_tuple(model), + std::forward_as_tuple(workers, flp)); } int getHierWorkers(const string& model) const { const auto mit = m_hierWorkers.find(model); // Assign a single worker if no specified. - return mit != m_hierWorkers.cend() ? mit->second : 0; + return mit != m_hierWorkers.cend() ? mit->second.workers() : 0; + } + FileLine* getHierWorkersFileLine(const string& model) const { + const auto mit = m_hierWorkers.find(model); + return mit != m_hierWorkers.cend() ? mit->second.flp() : v3Global.rootp()->fileline(); } - FileLine* getHierWorkersFileLine() const { return m_hierWorkersFileLine; } uint64_t getProfileData(const string& model, const string& key) const { const auto mit = m_profileData.find(model); if (mit == m_profileData.cend()) return 0; @@ -760,8 +774,8 @@ void V3Config::applyVarAttr(AstNodeModule* modulep, AstNodeFTask* ftaskp, AstVar int V3Config::getHierWorkers(const string& model) { return V3ConfigResolver::s().getHierWorkers(model); } -FileLine* V3Config::getHierWorkersFileLine() { - return V3ConfigResolver::s().getHierWorkersFileLine(); +FileLine* V3Config::getHierWorkersFileLine(const string& model) { + return V3ConfigResolver::s().getHierWorkersFileLine(model); } uint64_t V3Config::getProfileData(const string& hierDpi) { return V3ConfigResolver::s().getProfileData(hierDpi); diff --git a/src/V3Config.h b/src/V3Config.h index 34b1aad55..6cae9e04f 100644 --- a/src/V3Config.h +++ b/src/V3Config.h @@ -54,7 +54,7 @@ public: static void applyVarAttr(AstNodeModule* modulep, AstNodeFTask* ftaskp, AstVar* varp); static int getHierWorkers(const string& model); - static FileLine* getHierWorkersFileLine(); + static FileLine* getHierWorkersFileLine(const string& model); static uint64_t getProfileData(const string& hierDpi); static uint64_t getProfileData(const string& model, const string& key); static FileLine* getProfileDataFileLine(); diff --git a/src/V3HierBlock.cpp b/src/V3HierBlock.cpp index c0e2d8955..41d542993 100644 --- a/src/V3HierBlock.cpp +++ b/src/V3HierBlock.cpp @@ -192,8 +192,8 @@ V3StringList V3HierBlock::commandArgs(bool forCMake) const { const int blockThreads = V3Config::getHierWorkers(m_modp->origName()); if (blockThreads > 1) { if (hasParent()) { - V3Config::getHierWorkersFileLine()->v3warn( - E_UNSUPPORTED, "Specifying workers for nested hierarchical blocks"); + V3Config::getHierWorkersFileLine(m_modp->origName()) + ->v3warn(E_UNSUPPORTED, "Specifying workers for nested hierarchical blocks"); } else { if (v3Global.opt.threads() < blockThreads) { m_modp->v3error("Hierarchical blocks cannot be scheduled on more threads than in " diff --git a/test_regress/t/t_hier_block_threads_bad.out b/test_regress/t/t_hier_block_threads_bad.out index 108e3acbd..c82c09c9b 100644 --- a/test_regress/t/t_hier_block_threads_bad.out +++ b/test_regress/t/t_hier_block_threads_bad.out @@ -3,8 +3,8 @@ 23 | module Core(input clk); /*verilator hier_block*/ | ^~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error-UNSUPPORTED: t/t_hier_block_threads_bad.vlt:8:1: Specifying workers for nested hierarchical blocks - 8 | hier_workers -module "Core" -workers 8 +%Error-UNSUPPORTED: t/t_hier_block_threads_bad.vlt:9:1: Specifying workers for nested hierarchical blocks + 9 | hier_workers -module "SubCore" -workers 8 | ^~~~~~~~~~~~ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest %Error: Exiting due to