Don't elide a BUFZ that represents a continuous assignment.

To prevent a force from back propagating we need to keep a BUFZ
that represents a continuous assignment between two nets. This
only effects continuous assignments of the form assign out = in.
In general these are fairly rare so keeping them has minimal
impact on the simulation speed.
This commit is contained in:
Cary R 2010-09-05 12:30:03 -07:00 committed by Stephen Williams
parent c87186a15c
commit 5e1546faaf
1 changed files with 43 additions and 1 deletions

View File

@ -260,9 +260,43 @@ const char*drive_string(ivl_drive_t drive)
* on. The last net is selected as the output of the nexus.
*/
/*
* When checking if we can elide a buffer we need to keep the buffer
* if both the input and output for the buffer are connected only
* to netlist signals. This routine performs this check on the
* given nexus.
*/
static unsigned is_netlist_signal(ivl_net_logic_t net, ivl_nexus_t nex)
{
unsigned idx, rtn;
/* Assume that this is a netlist signal. */
rtn = 1;
for (idx = 0; idx < ivl_nexus_ptrs(nex); idx += 1) {
ivl_nexus_ptr_t nptr;
ivl_signal_t sptr;
nptr = ivl_nexus_ptr(nex, idx);
/* Skip a pointer to the buffer we're checking. */
if (ivl_nexus_ptr_log(nptr) == net) continue;
/* Check to see if this is a netlist signal. */
sptr = ivl_nexus_ptr_sig(nptr);
if (sptr && !ivl_signal_local(sptr)) continue;
/* If we get here then this is not just a netlist signal. */
rtn = 0;
break;
}
return rtn;
}
/*
* This tests a bufz device against an output receiver, and determines
* if the device can be skipped. If this function returns true, then a
* if the device can be skipped. If this function returns false, then a
* gate will be generated for this node. Otherwise, the code generator
* will connect its input to its output and skip the gate.
*/
@ -311,6 +345,14 @@ int can_elide_bufz(ivl_net_logic_t net, ivl_nexus_ptr_t nptr)
if (drive_count != 1)
return 0;
/* If both the input and output are netlist signal then we cannot
elide a BUFZ since it represents a continuous assignment. */
if (is_netlist_signal(net, ivl_logic_pin(net, 0)) &&
is_netlist_signal(net, ivl_logic_pin(net, 1)) &&
(ivl_logic_type(net) == IVL_LO_BUFZ)) {
return 0;
}
return 1;
}