From b226be7f98a350cb2eb3b0e6dc5d42f22ae989c7 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 23 Aug 2025 15:20:58 -0400 Subject: [PATCH] Fix to select UDPs when they are the only candidate for a top module. --- Changes | 1 + src/V3LinkCells.cpp | 15 +++++++++++++++ src/V3LinkLevel.cpp | 5 ++++- test_regress/t/t_udp_binary.py | 18 ++++++++++++++++++ test_regress/t/t_udp_binary.v | 14 ++++++++++++++ test_regress/t/t_udp_binary_top.py | 18 ++++++++++++++++++ test_regress/t/t_udp_binary_top.v | 18 ++++++++++++++++++ 7 files changed, 88 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_udp_binary.py create mode 100644 test_regress/t/t_udp_binary.v create mode 100755 test_regress/t/t_udp_binary_top.py create mode 100644 test_regress/t/t_udp_binary_top.v diff --git a/Changes b/Changes index 84b245735..ba61bbe9c 100644 --- a/Changes +++ b/Changes @@ -96,6 +96,7 @@ Verilator 5.039 devel * Fix queue extend to check bounds (#6324). [Aleksander Kiryk] * Fix gathering sensitivities from virtual interface members (#6325). [Aleksander Kiryk] * Fix FreeBSD missing headers (#6326). [Aleksander Kiryk] +* Fix to select UDPs when they are the only candidate for a top module. Verilator 5.038 2025-07-08 diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index eb2d71b6d..6334e504d 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -176,6 +176,20 @@ class LinkCellsVisitor final : public VNVisitor { return modp; } + static void removeLibFlag() { + // If the only NodeModules are in libraries, then presumably user + // wants to check the library, so clear library flag + if (!v3Global.opt.topModule().empty()) return; + for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; + nodep = VN_AS(nodep->nextp(), NodeModule)) { + if (!nodep->inLibrary()) return; + } + for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; + nodep = VN_AS(nodep->nextp(), NodeModule)) { + nodep->inLibrary(false); + } + } + // VISITORS void visit(AstNetlist* nodep) override { readModNames(); @@ -669,6 +683,7 @@ public: } else { m_origTopModuleName = v3Global.opt.topModule(); } + removeLibFlag(); iterate(nodep); } ~LinkCellsVisitor() override { diff --git a/src/V3LinkLevel.cpp b/src/V3LinkLevel.cpp index 6dd093cf3..a71f27bcf 100644 --- a/src/V3LinkLevel.cpp +++ b/src/V3LinkLevel.cpp @@ -47,7 +47,10 @@ void V3LinkLevel::modSortByLevel() { ModVec tops; // Top level modules for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep = VN_AS(nodep->nextp(), NodeModule)) { - if (nodep->level() <= 2 && !VN_IS(nodep, NotFoundModule)) tops.push_back(nodep); + if (nodep->level() <= 2 && !VN_IS(nodep, NotFoundModule)) { + UINFO(9, "top candidate " << nodep); + tops.push_back(nodep); + } mods.push_back(nodep); } if (tops.size() >= 2) { diff --git a/test_regress/t/t_udp_binary.py b/test_regress/t/t_udp_binary.py new file mode 100755 index 000000000..bd059b0f2 --- /dev/null +++ b/test_regress/t/t_udp_binary.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=['--binary']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_udp_binary.v b/test_regress/t/t_udp_binary.v new file mode 100644 index 000000000..f98676a16 --- /dev/null +++ b/test_regress/t/t_udp_binary.v @@ -0,0 +1,14 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +// Test that a standalone primitive can be a top level module + +primitive p(output id_2, input id_1); + table + 1 : 0; + 0 : 1; + endtable +endprimitive diff --git a/test_regress/t/t_udp_binary_top.py b/test_regress/t/t_udp_binary_top.py new file mode 100755 index 000000000..f33fc647b --- /dev/null +++ b/test_regress/t/t_udp_binary_top.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.compile(verilator_flags2=['--binary --top-module p']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_udp_binary_top.v b/test_regress/t/t_udp_binary_top.v new file mode 100644 index 000000000..f45244d3c --- /dev/null +++ b/test_regress/t/t_udp_binary_top.v @@ -0,0 +1,18 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +// Test that a standalone primitive can be a top level module + +primitive p(output id_2, input id_1); + table + 1 : 0; + 0 : 1; + endtable +endprimitive + +module t; // Overridden by --top-module + initial $stop; +endmodule