From 39c3e79a3cd01e0c0677439269296e58e2bce506 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Fri, 28 Mar 2025 17:04:09 +0000 Subject: [PATCH] Fix V3Gate assertion on eliminated circular logic (#5889) (#5898) Fixes #5889 --- src/V3Gate.cpp | 16 ++++++++++++-- test_regress/t/t_gate_elim_cycle.py | 16 ++++++++++++++ test_regress/t/t_gate_elim_cycle.v | 33 +++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_gate_elim_cycle.py create mode 100644 test_regress/t/t_gate_elim_cycle.v diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index abb8fff7d..b5269027a 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -869,8 +869,20 @@ class GateInline final { if (debug() >= 9) dstVtxp->nodep()->dumpTree(" inside: "); - UASSERT_OBJ(logicp != dstVtxp->nodep(), logicp, - "Circular logic should have been rejected by okVisitor"); + if (logicp == dstVtxp->nodep()) { + // This is a bit involved. The graph tells us that the logic is circular + // (driver is same as sink), however, okVisitor rejects a circular driver + // and we would not reach here if the driver logic was actually circular. + // The reason we end up here is because during graph building, the driver + // was ciruclar, however, after committing some substituions to it, it + // has become non-circualr due to V3Const being applied inside + // 'commitSubstitutions'. We will trust GateOkVisitor telling the truth + // that the logic is not actually circular, meaning this edge is not + // actually needed, can just delete it and move on. + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); + continue; + } + recordSubstitution(vscp, substp, dstVtxp->nodep()); // If the new replacement referred to a signal, diff --git a/test_regress/t/t_gate_elim_cycle.py b/test_regress/t/t_gate_elim_cycle.py new file mode 100755 index 000000000..147fe6faf --- /dev/null +++ b/test_regress/t/t_gate_elim_cycle.py @@ -0,0 +1,16 @@ +#!/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() + +test.passes() diff --git a/test_regress/t/t_gate_elim_cycle.v b/test_regress/t/t_gate_elim_cycle.v new file mode 100644 index 000000000..adc3ed1f0 --- /dev/null +++ b/test_regress/t/t_gate_elim_cycle.v @@ -0,0 +1,33 @@ +// 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 + +module GND(output G); + assign G = 0; +endmodule + +module CARRY2( + output [1:0] CO, + input CI, + input [1:0] DI, S +); + assign CO[0] = S[0] ? CI : DI[0]; + assign CO[1] = S[1] ? CO[0] : DI[1]; +endmodule + +module A; + wire const0; + wire ci; + GND GND ( + .G(const0) + ); + CARRY2 CARRY2 ( + .CO(), + + .CI(ci), + .DI({const0,const0}), + .S({const0,const0}) + ); +endmodule