Do not cprop through ternaries if the selector is an l-value.
It turns out that it is possible for an otherwise constant net
mux to be non-constant if there is a force that can drive the
net. This can be detected as an l-value reference to an otherwise
constant selector.
(cherry picked from commit abc4eb9d52)
This commit is contained in:
parent
d2a900d187
commit
04be3a6323
4
cprop.cc
4
cprop.cc
|
|
@ -823,6 +823,10 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
|||
|
||||
/* If the select input is constant, then replace with a BUFZ */
|
||||
bool flag = obj->pin_Sel().nexus()->drivers_constant();
|
||||
/* Note that this cannot be constant if there are assignments
|
||||
to this nexus. (Assignments include "force" to nets.) */
|
||||
flag &= !obj->pin_Sel().nexus()->assign_lval();
|
||||
|
||||
verinum::V sel_val = flag? obj->pin_Sel().nexus()->driven_value() : verinum::Vx;
|
||||
if ((sel_val != verinum::Vz) && (sel_val != verinum::Vx)) {
|
||||
NetBUFZ*tmp = new NetBUFZ(obj->scope(), obj->name(), obj->width());
|
||||
|
|
|
|||
19
net_link.cc
19
net_link.cc
|
|
@ -261,6 +261,25 @@ verinum::V Nexus::get_init() const
|
|||
return verinum::Vz;
|
||||
}
|
||||
|
||||
bool Nexus::assign_lval() const
|
||||
{
|
||||
assert(list_);
|
||||
for (Link*cur = list_ ; cur ; cur = cur->next_) {
|
||||
|
||||
const NetPins*obj;
|
||||
unsigned pin;
|
||||
cur->cur_link(obj, pin);
|
||||
const NetNet*net = dynamic_cast<const NetNet*> (obj);
|
||||
if (net == 0)
|
||||
continue;
|
||||
|
||||
if (net->peek_lref())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Nexus::drivers_present() const
|
||||
{
|
||||
assert(list_);
|
||||
|
|
|
|||
|
|
@ -347,6 +347,11 @@ class Nexus {
|
|||
|
||||
NetNet* pick_any_net();
|
||||
|
||||
/* This method returns true if there are any assignments that
|
||||
use this nexus as an l-value. This can be true if the nexus
|
||||
is a variable, but also if this is a net with a force. */
|
||||
bool assign_lval() const;
|
||||
|
||||
/* This method returns true if there are any drivers
|
||||
(including variables) attached to this nexus. */
|
||||
bool drivers_present() const;
|
||||
|
|
|
|||
Loading…
Reference in New Issue