1 /* gEDA - GPL Electronic Design Automation
2 * gnetlist - gEDA Netlist
3 * Copyright (C) 1998-2000 Ales V. Hvezda
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
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 USA
28 #include <libgeda/libgeda.h>
30 #include "../include/globals.h"
31 #include "../include/prototype.h"
33 #ifdef HAVE_LIBDMALLOC
37 void s_traverse_init(void)
39 netlist_head
= s_netlist_add(NULL
);
40 netlist_head
->nlid
= -1; /* head node */
42 graphical_netlist_head
= s_netlist_add(NULL
);
43 graphical_netlist_head
->nlid
= -1; /* head node */
47 ("\n\n------------------------------------------------------\n");
48 printf("Verbose mode legend\n\n");
49 printf("n : Found net\n");
50 printf("C : Found component (staring to traverse component)\n");
52 ("p : Found pin (starting to traverse pin / or examining pin)\n");
53 printf("P : Found end pin connection (end of this net)\n");
54 printf("R : Starting to rename a net\n");
55 printf("v : Found source attribute, traversing down\n");
56 printf("^ : Finished underlying source, going back up\n");
57 printf("u : Found a refdes which needs to be demangle\n");
59 ("U : Found a connected_to refdes which needs to be demangle\n");
61 ("------------------------------------------------------\n\n");
66 void s_traverse_start(TOPLEVEL
* pr_current
)
70 p_current
= pr_current
->page_head
;
72 while (p_current
!= NULL
) {
73 if (p_current
->pid
!= -1) {
75 /* only traverse pages which are toplevel, ie not underneath */
76 if (p_current
->object_head
&& p_current
->page_control
== 0) {
77 pr_current
->page_current
= p_current
;
78 s_traverse_sheet(pr_current
, p_current
->object_head
, NULL
);
83 p_current
= p_current
->next
;
86 /* now that all the sheets have been read, go through and do the */
87 /* post processing work */
88 s_netlist_post_process(pr_current
, netlist_head
);
90 /* Now match the graphical netlist with the net names already assigned */
91 s_netlist_name_named_nets(pr_current
, netlist_head
,
92 graphical_netlist_head
);
95 printf("\nInternal netlist representation:\n\n");
96 s_netlist_print(netlist_head
);
102 s_traverse_sheet(TOPLEVEL
* pr_current
, OBJECT
* start
,
109 gboolean is_graphical
=FALSE
;
112 printf("- Starting internal netlist creation\n");
117 while (o_current
!= NULL
) {
119 netlist
= s_netlist_return_tail(netlist_head
);
121 if (o_current
->type
== OBJ_PLACEHOLDER
) {
122 printf("WARNING: Found a placeholder/missing component, are you missing a symbol file? [%s]\n", o_current
->complex_basename
);
125 if (o_current
->type
== OBJ_COMPLEX
) {
128 printf("starting NEW component\n\n");
133 /* look for special tag */
134 temp
= o_attrib_search_component(o_current
, "graphical");
136 /* traverse graphical elements, but adding them to the
140 netlist
= s_netlist_return_tail(graphical_netlist_head
);
145 netlist
= s_netlist_add(netlist
);
146 netlist
->nlid
= o_current
->sid
;
148 /* search the single object only.... */
150 o_attrib_search_name_single(o_current
, "refdes", NULL
);
154 o_attrib_search_name_single(o_current
, "uref", NULL
); /* deprecated */
157 printf("WARNING: Found uref=%s, uref= is deprecated, please use refdes=\n", temp_uref
);
162 netlist
->component_uref
=
163 s_hierarchy_create_uref(pr_current
, temp_uref
,
166 netlist
->component_uref
= NULL
;
170 netlist
->hierarchy_tag
= g_strdup (hierarchy_tag
);
177 netlist
->object_ptr
= o_current
;
179 if (!netlist
->component_uref
) {
181 /* search of net attribute */
182 /* maybe symbol is not a component */
183 /* but a power / gnd symbol */
185 o_attrib_search_name(o_current
->complex->prim_objs
,
188 /* nope net attribute not found */
189 if ( (!temp
) && (!is_graphical
) ) {
192 "Could not find refdes on component and could not find any special attributes!\n");
194 netlist
->component_uref
=
195 (char *) g_malloc(sizeof(char) * strlen("U?") +
197 strcpy(netlist
->component_uref
, "U?");
201 printf("yeah... found a power symbol\n");
203 /* it's a power or some other special symbol */
204 netlist
->component_uref
= NULL
;
211 s_traverse_component(pr_current
, o_current
,
214 /* here is where you deal with the */
216 s_netattrib_handle(pr_current
, o_current
, netlist
,
219 /* now you need to traverse any underlying schematics */
220 if (pr_current
->hierarchy_traversal
== TRUE
) {
221 s_hierarchy_traverse(pr_current
, o_current
, netlist
);
225 o_current
= o_current
->next
;
231 CPINLIST
*s_traverse_component(TOPLEVEL
* pr_current
, OBJECT
* component
,
234 CPINLIST
*cpinlist_head
= NULL
;
235 CPINLIST
*cpins
= NULL
;
236 OBJECT
*o_current
= NULL
;
237 NET
*nets_head
= NULL
;
243 o_current
= component
->complex->prim_objs
;
245 cpinlist_head
= cpins
= s_cpinlist_add(NULL
);
248 while (o_current
!= NULL
) {
249 if (o_current
->type
== OBJ_PIN
) {
253 o_current
->visited
= 1;
256 cpins
= s_cpinlist_add(cpins
);
257 cpins
->plid
= o_current
->sid
;
259 /* search the object only */
260 cpins
->pin_number
= o_attrib_search_name_single(o_current
, "pinnumber",
264 o_attrib_search_name_single_count(o_current
, "pinlabel",
268 cpins
->pin_label
= temp
;
272 /* is this really need */
273 nets_head
= nets
= s_net_add(NULL
);
277 cl_current
= o_current
->conn_list
;
278 while (cl_current
!= NULL
) {
280 c_current
= (CONN
*) cl_current
->data
;
283 if (c_current
->other_object
!= NULL
) {
286 printf("c_current other_object, not NULL\n");
289 if (!c_current
->other_object
->visited
&&
290 c_current
->other_object
!= o_current
) {
292 nets
= s_net_add(nets
);
293 nets
->nid
= o_current
->sid
;
296 s_net_return_connected_string(pr_current
,
301 if (strstr(nets
->connected_to
, "POWER")) {
303 printf("going to find netname %s\n",
307 s_netattrib_return_netname(pr_current
,
312 nets
->net_name_has_priority
= TRUE
;
313 g_free(nets
->connected_to
);
314 nets
->connected_to
= NULL
;
317 printf("%s\n", nets
->connected_to
);
320 s_traverse_net(pr_current
, o_current
, nets
,
321 c_current
->other_object
,
324 s_traverse_clear_all_visited(pr_current
->
325 page_current
->object_head
);
329 cl_current
= cl_current
->next
;
332 cpins
->nets
= nets_head
;
333 /* s_net_print(nets); */
336 /* should pass in page_current in top level func */
338 s_traverse_clear_all_visited(pr_current
->page_current
->
341 o_current
= o_current
->next
;
345 return (cpinlist_head
);
349 void s_traverse_clear_all_visited(OBJECT
* object_head
)
353 o_current
= object_head
;
355 while (o_current
!= NULL
) {
358 if (o_current
->visited
) {
359 printf("%s\n", o_current
->name
);
363 o_current
->visited
= 0;
365 if (o_current
->type
== OBJ_COMPLEX
366 && o_current
->complex->prim_objs
) {
367 s_traverse_clear_all_visited(o_current
->complex->prim_objs
);
370 o_current
= o_current
->next
;
375 NET
*s_traverse_net(TOPLEVEL
* pr_current
, OBJECT
* previous_object
,
376 NET
* nets
, OBJECT
* object
, char *hierarchy_tag
)
386 new_net
= nets
= s_net_add(nets
);
387 new_net
->nid
= object
->sid
;
389 /* pins are not allowed to have the netname attribute attached to them */
390 if (o_current
->type
!= OBJ_PIN
) {
391 temp
= o_attrib_search_name_single(o_current
, "netname", NULL
);
395 s_hierarchy_create_netname(pr_current
, temp
,
400 /* search for the old label= attribute */
401 temp
= o_attrib_search_name_single(o_current
, "label", NULL
);
403 printf("WARNING: Found label=%s. label= is deprecated, please use netname=\n", temp
);
405 s_hierarchy_create_netname(pr_current
, temp
,
412 printf("inside traverse: %s\n", object
->name
);
415 if (object
->type
== OBJ_PIN
) {
419 new_net
->connected_to
=
420 s_net_return_connected_string(pr_current
, o_current
,
423 temp
= o_attrib_search_name_single_count(o_current
, "pinlabel", 0);
426 new_net
->pin_label
= temp
;
430 if (strstr(nets
->connected_to
, "POWER")) {
433 printf("going to find netname %s \n", nets
->connected_to
);
436 s_netattrib_return_netname(pr_current
, o_current
,
439 nets
->net_name_has_priority
= TRUE
;
440 g_free(nets
->connected_to
);
441 nets
->connected_to
= NULL
;
444 printf("traverse connected_to: %s\n", new_net
->connected_to
);
450 /*printf("Found net %s\n", object->name); */
455 /* this is not perfect yet and won't detect a loop... */
456 if (object
->visited
> 100) {
457 fprintf(stderr
, "Found a possible net/pin infinite connection\n");
461 cl_current
= object
->conn_list
;
462 while (cl_current
!= NULL
) {
464 c_current
= (CONN
*) cl_current
->data
;
466 if (c_current
->other_object
!= NULL
) {
469 printf("c_current %s visited: %d\n",
470 c_current
->other_object
->name
,
471 c_current
->other_object
->visited
);
474 if (!c_current
->other_object
->visited
&&
475 c_current
->other_object
!= o_current
&&
476 c_current
->other_object
->type
!= OBJ_BUS
) {
479 s_traverse_net(pr_current
, object
, nets
,
480 c_current
->other_object
, hierarchy_tag
);
484 cl_current
= cl_current
->next
;