From 5e1546faaf9567f14776bf5d3a6933c551ca9219 Mon Sep 17 00:00:00 2001 From: Cary R Date: Sun, 5 Sep 2010 12:30:03 -0700 Subject: [PATCH] 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. --- tgt-vvp/vvp_scope.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index aed28c035..da38e9647 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -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; }