2 * Copyright (c) 1999 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 #ident "$Id: nodangle.cc,v 1.21 2004/02/20 18:53:35 steve Exp $"
26 * This functor scans the design looking for dangling objects and
27 * excess local signals. These deletions are not necessarily required
28 * for proper functioning of anything, but they can clean up the
29 * appearance of design files that are generated.
33 # include "compiler.h"
35 class nodangle_f
: public functor_t
{
37 void event(Design
*des
, NetEvent
*ev
);
38 void signal(Design
*des
, NetNet
*sig
);
41 unsigned stotal
, etotal
;
44 void nodangle_f::event(Design
*des
, NetEvent
*ev
)
46 /* If there are no references to this event, then go right
47 ahead and delete in. There is no use looking further at
49 if ((ev
->nwait() + ev
->ntrig() + ev
->nexpr()) == 0) {
55 /* Try to remove duplicate probes from the event. */
56 for (unsigned idx
= 0 ; idx
< ev
->nprobe() ; idx
+= 1) {
57 unsigned jdx
= idx
+ 1;
58 while (jdx
< ev
->nprobe()) {
59 NetEvProbe
*ip
= ev
->probe(idx
);
60 NetEvProbe
*jp
= ev
->probe(jdx
);
62 if (ip
->edge() != jp
->edge()) {
67 bool fully_connected
= true;
68 for (unsigned jpin
= 0; jpin
< jp
->pin_count(); jpin
+= 1) {
70 bool connected_flag
= false;
71 for (ipin
= 0 ; ipin
< ip
->pin_count(); ipin
+= 1)
72 if (connected(ip
->pin(ipin
), jp
->pin(jpin
))) {
73 connected_flag
= true;
77 if (!connected_flag
) {
78 fully_connected
= false;
83 if (fully_connected
) {
91 /* Try to find all the events that are similar to me, and
92 replace their references with references to me. */
93 list
<NetEvent
*> match
;
94 ev
->find_similar_event(match
);
95 for (list
<NetEvent
*>::iterator idx
= match
.begin()
96 ; idx
!= match
.end() ; idx
++) {
100 tmp
->replace_event(ev
);
105 void nodangle_f::signal(Design
*des
, NetNet
*sig
)
107 /* Cannot delete signals referenced in an expression
109 if (sig
->get_refs() > 0)
112 /* Cannot delete the ports of tasks or functions. There are
113 too many places where they are referenced. */
114 if ((sig
->port_type() != NetNet::NOT_A_PORT
)
115 && (sig
->scope()->type() == NetScope::TASK
))
118 if ((sig
->port_type() != NetNet::NOT_A_PORT
)
119 && (sig
->scope()->type() == NetScope::FUNC
))
122 /* Can't delete ports of cells. */
123 if ((sig
->port_type() != NetNet::NOT_A_PORT
)
124 && (sig
->scope()->attribute(perm_string::literal("ivl_synthesis_cell")) != verinum()))
127 /* Check to see if the signal is completely unconnected. If
128 all the bits are unlinked, then delete it. */
129 bool linked_flag
= false;
130 for (unsigned idx
= 0 ; idx
< sig
->pin_count() ; idx
+= 1)
131 if (sig
->pin(idx
).is_linked()) {
142 /* The remaining things can only be done to synthesized
143 signals, not ones that appear in the original Verilog. */
144 if (! sig
->local_flag())
147 /* Check to see if there is some significant signal connected
148 to every pin of this signal. */
149 unsigned significant_flags
= 0;
150 for (unsigned idx
= 0 ; idx
< sig
->pin_count() ; idx
+= 1) {
151 Nexus
*nex
= sig
->pin(idx
).nexus();
153 for (Link
*cur
= nex
->first_nlink()
154 ; cur
; cur
= cur
->next_nlink()) {
156 if (cur
== &sig
->pin(idx
))
159 NetNet
*cursig
= dynamic_cast<NetNet
*>(cur
->get_obj());
163 if (cursig
->local_flag())
166 significant_flags
+= 1;
170 if (significant_flags
<= idx
)
174 /* If every pin is connected to another significant signal,
175 then I can delete this one. */
176 if (significant_flags
== sig
->pin_count()) {
183 void nodangle(Design
*des
)
186 unsigned count_iterations
= 0;
193 count_iterations
+= 1;
196 cout
<< " ... " << count_iterations
<< " iterations"
197 << " deleted " << fun
.stotal
<< " dangling signals"
198 << " and " << fun
.etotal
<< " events."
199 << " (count=" << fun
.count_
<< ")" << endl
;
202 } while (fun
.count_
> 0);
207 * $Log: nodangle.cc,v $
208 * Revision 1.21 2004/02/20 18:53:35 steve
209 * Addtrbute keys are perm_strings.
211 * Revision 1.20 2004/01/15 06:04:19 steve
212 * Remove duplicate NetEvProbe objects in nodangle.
214 * Revision 1.19 2003/06/25 04:46:03 steve
215 * Do not elide ports of cells.
217 * Revision 1.18 2003/04/22 04:48:30 steve
218 * Support event names as expressions elements.
220 * Revision 1.17 2002/08/12 01:35:00 steve
221 * conditional ident string using autoconfig.
223 * Revision 1.16 2002/07/24 16:24:45 steve
224 * Rewrite find_similar_event to support doing
225 * all event matching and replacement in one
226 * shot, saving time in the scans.
228 * Revision 1.15 2002/05/26 01:39:02 steve
229 * Carry Verilog 2001 attributes with processes,
230 * all the way through to the ivl_target API.
232 * Divide signal reference counts between rval
233 * and lval references.
235 * Revision 1.14 2002/02/02 06:13:38 steve
236 * event find_similar should not find self.
238 * Revision 1.13 2001/07/27 02:41:55 steve
239 * Fix binding of dangling function ports. do not elide them.
241 * Revision 1.12 2001/07/25 03:10:49 steve
242 * Create a config.h.in file to hold all the config
243 * junk, and support gcc 3.0. (Stephan Boettcher)
245 * Revision 1.11 2001/02/17 05:14:35 steve
246 * Cannot elide task ports.
248 * Revision 1.10 2000/11/19 20:48:53 steve
249 * Killing some signals might make others killable.
251 * Revision 1.9 2000/11/18 05:12:45 steve
252 * Delete unreferenced signals no matter what.
254 * Revision 1.8 2000/06/25 19:59:42 steve
255 * Redesign Links to include the Nexus class that
256 * carries properties of the connected set of links.
258 * Revision 1.7 2000/05/31 02:26:49 steve
259 * Globally merge redundant event objects.
261 * Revision 1.6 2000/05/07 04:37:56 steve
262 * Carry strength values from Verilog source to the
263 * pform and netlist for gates.
265 * Change vvm constants to use the driver_t to drive
266 * a constant value. This works better if there are
267 * multiple drivers on a signal.
269 * Revision 1.5 2000/04/28 21:00:29 steve
270 * Over agressive signal elimination in constant probadation.
272 * Revision 1.4 2000/04/18 04:50:20 steve
273 * Clean up unneeded NetEvent objects.
275 * Revision 1.3 2000/02/23 02:56:55 steve
276 * Macintosh compilers do not support ident.
278 * Revision 1.2 1999/11/28 23:42:02 steve
279 * NetESignal object no longer need to be NetNode
280 * objects. Let them keep a pointer to NetNet objects.
282 * Revision 1.1 1999/11/18 03:52:20 steve
283 * Turn NetTmp objects into normal local NetNet objects,
284 * and add the nodangle functor to clean up the local
285 * symbols generated by elaboration and other steps.