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.
This commit is contained in:
Martin Whitaker 2025-11-11 21:43:29 +00:00
parent 3b209301e2
commit 28717b4de7
2 changed files with 11 additions and 5 deletions

View File

@ -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.

View File

@ -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 <NetEConst*> (base_)) {
if (/* const NetEConst *val = */ dynamic_cast <NetEConst*> (base_)) {
assert(select_type() == IVL_SEL_OTHER);
if (const NetESignal *sig = dynamic_cast<NetESignal*> (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;