From 28717b4de7134b8f79fd0fa87e9b29e5a0f9895f Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Tue, 11 Nov 2025 21:43:29 +0000 Subject: [PATCH] Don't include duplicate nodes in NetEvent objects (issue #1286). Currently, when a constant bit/part select is found in the implicit sensitivity list for an always_* construct, it is replaced by the entire signal. If there is more than one bit/part select from the same signal, that signal gets added to the list multiple times. This breaks the algorithm used to detect duplicate events in the nodangle functor, causing it to erroneously merge non-identical events in some cases. The proper fix is to support sensitivity at the bit/part level, as required by IEEE 1800. But for now, just make sure we only include the entire signal once, regardless of how many different bit/part selects we find. Enhance the "sorry" message to report which signals are contributing excessively to the process sensitivity. --- elaborate.cc | 6 ++---- net_nex_input.cc | 10 +++++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/elaborate.cc b/elaborate.cc index 05432eb8f..5800e8f5b 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -4908,11 +4908,9 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope, unsigned vwid = nset->at(idx).lnk.nexus()->vector_width(); // Is this a part select? if (always_sens_ && (wid != vwid)) { - cerr << get_fileline() << ": sorry: constant " - "selects in always_* processes are not " - "currently supported (all bits will be " - "included)." << endl; # if 0 +// Once this is fixed, enable constant bit/part select sensitivity in +// NetESelect::nex_input(). unsigned base = nset->at(idx).base; cerr << get_fileline() << ": base = " << base << endl; // FIXME: make this work with selects that go before the base. diff --git a/net_nex_input.cc b/net_nex_input.cc index cd0e26cf0..65f454cf8 100644 --- a/net_nex_input.cc +++ b/net_nex_input.cc @@ -144,12 +144,20 @@ NexusSet* NetESelect::nex_input(bool rem_out, bool always_sens, bool nested_func NexusSet*tmp = expr_->nex_input(rem_out, always_sens, nested_func); bool const_select = result->size() == 0; if (always_sens && const_select) { - if (const NetEConst *val = dynamic_cast (base_)) { + if (/* const NetEConst *val = */ dynamic_cast (base_)) { assert(select_type() == IVL_SEL_OTHER); if (const NetESignal *sig = dynamic_cast (expr_)) { + cerr << get_fileline() << ": sorry: constant selects " + "in always_* processes are not fully supported " + "(the process will be sensitive to all bits in '" + << *sig << "')." << endl; +#if 0 +// Enable this code once PEventStatement::elaborate_st() has been enhanced to +// support bit/part select sensitivity. delete tmp; tmp = sig->nex_input_base(rem_out, always_sens, nested_func, val->value().as_unsigned(), expr_width()); +#endif } else { cerr << get_fileline() << ": Sorry, cannot determine the sensitivity " << "for the select of " << *expr_ << ", using all bits." << endl;