Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2 | Rev 11 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* |
1 | /* |
2 | * $Header: c:\\cygwin\\cvsroot/Vert03/vertlib/jumpering.c,v 1.1.1.1 2003/11/04 23:34:57 mjames |
2 | * $Header: c:\\cygwin\\cvsroot/Vert03/vertlib/jumpering.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $ |
3 | * Exp $ |
- | |
4 | * |
3 | * |
5 | * $Log: jumpering.c,v $ |
4 | * $Log: jumpering.c,v $ |
6 | * Revision 1.1.1.1 2003/11/04 23:34:57 mjames |
5 | * Revision 1.1.1.1 2003/11/04 23:34:57 mjames |
7 | * Imported into local repositrory |
6 | * Imported into local repositrory |
8 | * |
7 | * |
Line 52... | Line 51... | ||
52 | * Revision 1.1.1.1 2000/10/19 21:58:38 mjames |
51 | * Revision 1.1.1.1 2000/10/19 21:58:38 mjames |
53 | * Mike put it here |
52 | * Mike put it here |
54 | * |
53 | * |
55 | * Revision 1.32 2000/10/04 10:37:06 10:37:06 mjames (Mike James) |
54 | * Revision 1.32 2000/10/04 10:37:06 10:37:06 mjames (Mike James) |
56 | * Modified for Vertical2 : support COMPONENTS and SIGNALS |
55 | * Modified for Vertical2 : support COMPONENTS and SIGNALS |
57 | * |
56 | * |
58 | * Revision 1.32 2000/10/04 10:37:06 10:37:06 mjames (Mike James) |
57 | * Revision 1.32 2000/10/04 10:37:06 10:37:06 mjames (Mike James) |
59 | * Part of Release PSAVAT01 |
58 | * Part of Release PSAVAT01 |
60 | * |
59 | * |
61 | * Revision 1.31 2000/10/02 11:04:15 11:04:15 mjames (Mike James) |
60 | * Revision 1.31 2000/10/02 11:04:15 11:04:15 mjames (Mike James) |
62 | * new_vhdl |
61 | * new_vhdl |
63 | * |
62 | * |
64 | * Revision 1.30 2000/09/27 14:42:16 14:42:16 mjames (Mike James) |
63 | * Revision 1.30 2000/09/27 14:42:16 14:42:16 mjames (Mike James) |
65 | * Part of Release Sep_27_ST_2000 |
64 | * Part of Release Sep_27_ST_2000 |
66 | * |
65 | * |
67 | * Revision 1.29 2000/09/21 10:15:46 10:15:46 mjames (Mike James) |
66 | * Revision 1.29 2000/09/21 10:15:46 10:15:46 mjames (Mike James) |
68 | * Part of Release Sep21Alpha |
67 | * Part of Release Sep21Alpha |
69 | * |
68 | * |
70 | * Revision 1.28 2000/09/21 09:46:54 09:46:54 mjames (Mike James) |
69 | * Revision 1.28 2000/09/21 09:46:54 09:46:54 mjames (Mike James) |
71 | * Added code to deal with pin equivalents |
70 | * Added code to deal with pin equivalents |
72 | * |
71 | * |
73 | * Revision 1.27 2000/08/25 09:57:12 09:57:12 mjames (Mike James) |
72 | * Revision 1.27 2000/08/25 09:57:12 09:57:12 mjames (Mike James) |
74 | * Part of Release Aug25_alpha |
73 | * Part of Release Aug25_alpha |
75 | * |
74 | * |
76 | * Revision 1.26 2000/08/16 08:57:28 08:57:28 mjames (Mike James) |
75 | * Revision 1.26 2000/08/16 08:57:28 08:57:28 mjames (Mike James) |
77 | * Part of Release CD01_Aug2000 |
76 | * Part of Release CD01_Aug2000 |
78 | * |
77 | * |
79 | * Revision 1.25 2000/08/14 14:45:10 14:45:10 mjames (Mike James) |
78 | * Revision 1.25 2000/08/14 14:45:10 14:45:10 mjames (Mike James) |
80 | * Part of Release Aug_14_2000 |
79 | * Part of Release Aug_14_2000 |
81 | * |
80 | * |
82 | * Revision 1.24 2000/08/14 14:42:53 14:42:53 mjames (Mike James) |
81 | * Revision 1.24 2000/08/14 14:42:53 14:42:53 mjames (Mike James) |
83 | * Changed checks for hierarchical jumpers |
82 | * Changed checks for hierarchical jumpers |
84 | * |
83 | * |
85 | * Revision 1.23 2000/08/11 08:30:30 08:30:30 mjames (Mike James) |
84 | * Revision 1.23 2000/08/11 08:30:30 08:30:30 mjames (Mike James) |
86 | * Part of Release Aug_11_2000 |
85 | * Part of Release Aug_11_2000 |
87 | * |
86 | * |
88 | * Revision 1.22 2000/08/09 10:31:44 10:31:44 mjames (Mike James) |
87 | * Revision 1.22 2000/08/09 10:31:44 10:31:44 mjames (Mike James) |
89 | * Part of Release Aug__9_2000 |
88 | * Part of Release Aug__9_2000 |
90 | * |
89 | * |
91 | * Revision 1.21 2000/05/31 11:42:53 11:42:53 mjames (Mike James) |
90 | * Revision 1.21 2000/05/31 11:42:53 11:42:53 mjames (Mike James) |
92 | * Part of Release May_31_2000 |
91 | * Part of Release May_31_2000 |
93 | * |
92 | * |
94 | * Revision 1.20 2000/05/08 17:01:35 17:01:35 mjames (Mike James) |
93 | * Revision 1.20 2000/05/08 17:01:35 17:01:35 mjames (Mike James) |
95 | * Part of Release May__8_2000 |
94 | * Part of Release May__8_2000 |
96 | * |
95 | * |
97 | * Revision 1.19 2000/05/08 16:59:29 16:59:29 mjames (Mike James) |
96 | * Revision 1.19 2000/05/08 16:59:29 16:59:29 mjames (Mike James) |
98 | * Part of Release May__8_2000 |
97 | * Part of Release May__8_2000 |
99 | * |
98 | * |
100 | * Revision 1.18 2000/05/08 16:57:05 16:57:05 mjames (Mike James) |
99 | * Revision 1.18 2000/05/08 16:57:05 16:57:05 mjames (Mike James) |
101 | * Part of Release May__8_2000 |
100 | * Part of Release May__8_2000 |
102 | * |
101 | * |
103 | * Revision 1.17 2000/03/08 16:19:09 16:19:09 mjames (Mike James) |
102 | * Revision 1.17 2000/03/08 16:19:09 16:19:09 mjames (Mike James) |
104 | * New version including PC |
103 | * New version including PC |
105 | * |
104 | * |
106 | * Revision 1.14 2000/01/20 15:58:45 15:58:45 mjames (Mike James) |
105 | * Revision 1.14 2000/01/20 15:58:45 15:58:45 mjames (Mike James) |
107 | * Part of Release R22 |
106 | * Part of Release R22 |
108 | * |
107 | * |
109 | * Revision 1.13 99/12/22 11:15:25 11:15:25 mjames (Mike James) |
108 | * Revision 1.13 99/12/22 11:15:25 11:15:25 mjames (Mike James) |
110 | * Part of Release Dec_22_1999 |
109 | * Part of Release Dec_22_1999 |
111 | * |
110 | * |
112 | * Revision 1.12 99/06/25 14:35:36 14:35:36 mjames (Mike James) |
111 | * Revision 1.12 99/06/25 14:35:36 14:35:36 mjames (Mike James) |
113 | * Added in reference to expression.h, but no changes made |
112 | * Added in reference to expression.h, but no changes made |
114 | * to the function of acfread yet. |
113 | * to the function of acfread yet. |
115 | * |
114 | * |
116 | * Revision 1.11 99/05/04 09:51:47 09:51:47 mjames (Mike James) |
115 | * Revision 1.11 99/05/04 09:51:47 09:51:47 mjames (Mike James) |
117 | * General checkin |
116 | * General checkin |
118 | * ls |
117 | * ls |
119 | * |
118 | * |
120 | * Revision 1.9 98/11/30 13:48:12 13:48:12 mjames (Mike James) |
119 | * Revision 1.9 98/11/30 13:48:12 13:48:12 mjames (Mike James) |
121 | * Corrected a create-jumper-with-no-nodes = core dump |
120 | * Corrected a create-jumper-with-no-nodes = core dump |
122 | * problem |
121 | * problem |
123 | * |
122 | * |
124 | * Revision 1.8 98/11/27 15:15:08 15:15:08 mjames (Mike James) |
123 | * Revision 1.8 98/11/27 15:15:08 15:15:08 mjames (Mike James) |
125 | * Amended algorithm to work with newer database |
124 | * Amended algorithm to work with newer database |
126 | * format |
125 | * format |
127 | * |
126 | * |
128 | * Revision 1.7 98/11/25 12:46:54 12:46:54 mjames (Mike James) |
127 | * Revision 1.7 98/11/25 12:46:54 12:46:54 mjames (Mike James) |
129 | * Checked in with some errors to do with not creating a jumper name !! |
128 | * Checked in with some errors to do with not creating a jumper name !! |
130 | * |
129 | * |
131 | * Revision 1.6 98/11/16 13:18:30 13:18:30 mjames (Mike James) |
130 | * Revision 1.6 98/11/16 13:18:30 13:18:30 mjames (Mike James) |
132 | * |
131 | * |
133 | * Revision 1.5 98/03/16 11:32:31 11:32:31 mjames (Mike James) |
132 | * Revision 1.5 98/03/16 11:32:31 11:32:31 mjames (Mike James) |
134 | * Attempting to correct the jumpering of already jumpered jumper lists. |
133 | * Attempting to correct the jumpering of already jumpered jumper lists. |
135 | * |
134 | * |
136 | * Revision 1.4 98/02/11 11:26:28 11:26:28 mjames (Mike James) |
135 | * Revision 1.4 98/02/11 11:26:28 11:26:28 mjames (Mike James) |
137 | * Checked in for version 6.2a |
136 | * Checked in for version 6.2a |
138 | * |
137 | * |
139 | * Revision 1.3 97/04/23 08:42:54 08:42:54 mjames (Mike James) |
138 | * Revision 1.3 97/04/23 08:42:54 08:42:54 mjames (Mike James) |
140 | * CHecked in for release rel23041997 |
139 | * CHecked in for release rel23041997 |
141 | * |
140 | * |
142 | * Revision 1.2 96/12/13 08:43:23 08:43:23 mjames (Mike James) |
141 | * Revision 1.2 96/12/13 08:43:23 08:43:23 mjames (Mike James) |
143 | * Update to v5.1, added Write ID , exact routing |
142 | * Update to v5.1, added Write ID , exact routing |
144 | * |
143 | * |
145 | * Revision 1.1 96/08/06 13:39:40 13:39:40 mjames (Mike James) |
144 | * Revision 1.1 96/08/06 13:39:40 13:39:40 mjames (Mike James) |
146 | * Initial revision |
145 | * Initial revision |
147 | * |
146 | * |
148 | * */ |
147 | * */ |
149 | 148 | ||
- | 149 | #include <stdio.h> |
|
150 | #include "jumpering.h" |
150 | #include <string.h> |
- | 151 | #include <stdlib.h> |
|
- | 152 | #include <ctype.h> |
|
151 | 153 | ||
152 | #include "cmdlog.h" |
- | |
153 | #include "cmdparse.h" |
- | |
154 | #include "database.h" |
154 | #include "vertcl_main.h" |
155 | #include "expression.h" |
155 | #include "expression.h" |
156 | #include "generic.h" |
156 | #include "generic.h" |
- | 157 | #include "database.h" |
|
157 | #include "routing.h" |
158 | #include "routing.h" |
158 | #include "vertcl_main.h" |
159 | #include "jumpering.h" |
159 | - | ||
160 | #include <ctype.h> |
160 | #include "cmdparse.h" |
161 | #include <stdio.h> |
- | |
162 | #include <stdlib.h> |
161 | #include "cmdlog.h" |
163 | #include <string.h> |
- | |
164 | 162 | ||
165 | #ident \ |
- | |
166 | "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/jumpering.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $" |
163 | #ident "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/jumpering.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $" |
167 | 164 | ||
168 | /* resolve not routable H or L */ |
165 | /* resolve not routable H or L */ |
169 | HowRouted_t routing_resolve (HowRouted_t curr, HowRouted_t next) |
166 | HowRouted_t routing_resolve( HowRouted_t curr, HowRouted_t next) |
170 | { |
167 | { |
171 | /* the H property can be destroyed if it meets L or plain not_routable */ |
168 | /* the H property can be destroyed if it meets L or plain not_routable */ |
172 | if (curr == Not_Routable_H) |
169 | if (curr == Not_Routable_H) |
173 | { |
170 | { |
174 | if (next == Not_Routable || next == Not_Routable_L) |
171 | if (next == Not_Routable || next == Not_Routable_L) |
175 | return Not_Routable; |
172 | return Not_Routable; |
176 | } |
173 | } |
177 | if (curr == Not_Routable_L) |
174 | if (curr == Not_Routable_L) |
178 | { |
175 | { |
179 | if (next == Not_Routable || next == Not_Routable_H) |
176 | if (next == Not_Routable || next == Not_Routable_H) |
180 | return Not_Routable; |
177 | return Not_Routable; |
181 | } |
178 | } |
182 | return next; |
179 | return next; |
- | 180 | } |
|
183 | } |
181 | |
184 | 182 | ||
185 | /* takes a net and removes it from the list of nets directly searchable |
183 | /* takes a net and removes it from the list of nets directly searchable |
186 | by routing algorithms, copying all its node references to the new net, |
184 | by routing algorithms, copying all its node references to the new net, |
187 | This is used in creating jumpers */ |
185 | This is used in creating jumpers */ |
188 | __declspec(dllexport) int transfer_net_to_subnet (net_t **list, net_t *topnet, net_t *subnet) |
186 | __declspec (dllexport) int transfer_net_to_subnet(net_t ** list,net_t * topnet, net_t * subnet) |
189 | { |
187 | { |
190 | net_t *prev_net; |
188 | net_t * prev_net; |
191 | net_t *next_net; |
189 | net_t * next_net; |
192 | char *subnet_orig_ident; |
190 | char * subnet_orig_ident; |
193 | HowRouted_t subnet_how_routed; |
191 | HowRouted_t subnet_how_routed; |
194 | int hierarchy; |
192 | int hierarchy; |
195 | hierarchy = 0; |
193 | hierarchy = 0; |
196 | 194 | ||
197 | /* algorithms check to see if there is a hierarchy of jumpers. |
195 | /* algorithms check to see if there is a hierarchy of jumpers. |
198 | if there is then check to see if the jumper is basically a connection |
196 | if there is then check to see if the jumper is basically a connection |
199 | to itself. If it is give up. */ |
197 | to itself. If it is give up. */ |
200 | 198 | ||
201 | subnet_how_routed = subnet->how_routed; |
199 | |
202 | subnet_orig_ident = subnet->identifier; |
200 | subnet_how_routed = subnet->how_routed; |
203 | 201 | subnet_orig_ident = subnet-> identifier; |
|
204 | /* Log(LOG_GENERAL,"# JUMPER: Net '%s' jumpered to '%s'\n", |
202 | |
205 | topnet->identifier,subnet->identifier); |
203 | /* Log(LOG_GENERAL,"# JUMPER: Net '%s' jumpered to '%s'\n", |
206 | */ |
204 | topnet->identifier,subnet->identifier); |
207 | if (subnet->join_parent) |
205 | */ |
208 | { |
206 | if(subnet->join_parent) { |
209 | hierarchy = 1; |
207 | hierarchy = 1; |
210 | while (subnet->join_parent) |
208 | while(subnet->join_parent) { |
211 | { |
209 | /* Log(LOG_GENERAL,"# Info : Net '%s' is already jumpered to '%s': trying parent jumper\n", |
212 | /* Log(LOG_GENERAL,"# Info : Net '%s' is already jumpered to '%s': |
210 | subnet->identifier,subnet->join_parent->identifier); |
213 | trying parent jumper\n", |
211 | */ |
214 | subnet->identifier,subnet->join_parent->identifier); |
212 | subnet = subnet->join_parent; |
215 | */ |
213 | } |
216 | subnet = subnet->join_parent; |
214 | |
217 | } |
215 | } |
218 | } |
216 | |
219 | 217 | if(topnet==subnet) { |
|
220 | if (topnet == subnet) |
218 | Log(LOG_ERROR,"# Error : - Cant join a net to itself !!! %s to %s : Suppressing Jumper\n", |
221 | { |
219 | subnet_orig_ident,topnet->identifier); |
222 | Log ( |
220 | return 0; |
223 | LOG_ERROR, |
221 | } |
224 | "# Error : - Cant join a net to itself !!! %s to %s : Suppressing " |
222 | else |
225 | "Jumper\n", |
223 | if(hierarchy) |
226 | subnet_orig_ident, |
224 | { |
227 | topnet->identifier); |
225 | Log(LOG_GENERAL,"# -- Info : Net '%s' will be jumpered via '%s' to '%s' \n", |
228 | return 0; |
226 | subnet_orig_ident,subnet->identifier,topnet->identifier); |
229 | } |
227 | } |
230 | else if (hierarchy) |
228 | prev_net = subnet->prev; |
231 | { |
229 | next_net = subnet->next; |
232 | Log ( |
230 | |
233 | LOG_GENERAL, |
231 | |
234 | "# -- Info : Net '%s' will be jumpered via '%s' to '%s' \n", |
232 | |
235 | subnet_orig_ident, |
233 | /* Remove subnet from directly searchable list */ |
236 | subnet->identifier, |
234 | |
237 | topnet->identifier); |
235 | /* if at head of list, correct list and point back at NULL */ |
238 | } |
236 | if(subnet== * list) { |
239 | prev_net = subnet->prev; |
237 | *list = next_net; |
240 | next_net = subnet->next; |
238 | if(next_net) |
241 | 239 | next_net->prev = NULL; |
|
242 | /* Remove subnet from directly searchable list */ |
240 | } |
243 | 241 | else |
|
244 | /* if at head of list, correct list and point back at NULL */ |
242 | if(next_net) |
245 | if (subnet == *list) |
243 | next_net->prev = subnet->prev; |
246 | { |
244 | if(prev_net) |
247 | *list = next_net; |
245 | prev_net->next = subnet->next; |
248 | if (next_net) |
246 | |
249 | next_net->prev = NULL; |
247 | /* attach net to topnet's subnet list */ |
250 | } |
248 | /* printf("before: topnet->subnets = %p\n",topnet->subnets); */ |
251 | else if (next_net) |
249 | /* printf("before: subnet = %p\n",subnet); */ |
252 | next_net->prev = subnet->prev; |
250 | |
253 | if (prev_net) |
251 | subnet->prev = NULL; |
254 | prev_net->next = subnet->next; |
252 | subnet->next = NULL; |
255 | 253 | subnet->joined_nets = topnet->subnets; /* The subnets are linked horizontally via |
|
256 | /* attach net to topnet's subnet list */ |
254 | the 'joined_nets' rather than subnet pointer now */ |
257 | /* printf("before: topnet->subnets = %p\n",topnet->subnets); */ |
255 | |
258 | /* printf("before: subnet = %p\n",subnet); */ |
256 | subnet->join_parent = topnet; /* The subnet is joined to the parent */ |
259 | 257 | topnet->join_parent = NULL; /* this net does not have a parent */ |
|
260 | subnet->prev = NULL; |
258 | topnet->subnets = subnet; |
261 | subnet->next = NULL; |
259 | |
262 | subnet->joined_nets = topnet->subnets; /* The subnets are linked horizontally via |
260 | /* propagate up properties */ |
263 | the 'joined_nets' rather than subnet pointer now */ |
261 | |
264 | 262 | if (subnet->has_fix_location) |
|
265 | subnet->join_parent = topnet; /* The subnet is joined to the parent */ |
263 | topnet->has_fix_location = 1; |
266 | topnet->join_parent = NULL; /* this net does not have a parent */ |
264 | |
267 | topnet->subnets = subnet; |
265 | |
268 | 266 | if (IS_NOT_ROUTABLE(subnet_how_routed)) |
|
269 | /* propagate up properties */ |
267 | { |
270 | 268 | Log(LOG_ERROR,"# Warning - Jumpering '%s' and '%s' will be NON ROUTABLE\n", |
|
271 | if (subnet->has_fix_location) |
269 | subnet->identifier,topnet->identifier); |
272 | topnet->has_fix_location = 1; |
270 | |
273 | 271 | } |
|
274 | if (IS_NOT_ROUTABLE (subnet_how_routed)) |
272 | topnet->how_routed = routing_resolve(topnet->how_routed,subnet_how_routed); |
275 | { |
273 | |
276 | Log ( |
274 | |
277 | LOG_ERROR, |
275 | |
278 | "# Warning - Jumpering '%s' and '%s' will be NON ROUTABLE\n", |
276 | /* subnet->name = topnet->name;*/ |
279 | subnet->identifier, |
277 | |
280 | topnet->identifier); |
278 | |
281 | } |
279 | |
282 | topnet->how_routed = routing_resolve (topnet->how_routed, subnet_how_routed); |
280 | /* printf("after: topnet->subnets = %p\n",topnet->subnets); */ |
283 | 281 | /* printf("after: subnet->next = %p\n",subnet->next); */ |
|
284 | /* subnet->name = topnet->name;*/ |
282 | |
285 | 283 | ||
286 | /* printf("after: topnet->subnets = %p\n",topnet->subnets); */ |
284 | /* now copy the noderef list from subnet to topnet */ |
287 | /* printf("after: subnet->next = %p\n",subnet->next); */ |
285 | { |
288 | 286 | noderef_t * newref ; |
|
289 | /* now copy the noderef list from subnet to topnet */ |
287 | noderef_t * oldref = subnet->nodes; |
290 | { |
288 | while(oldref) { |
291 | noderef_t *newref; |
289 | /* create a new node reference */ |
292 | noderef_t *oldref = subnet->nodes; |
290 | newref = calloc(1,sizeof(noderef_t)); |
293 | while (oldref) |
291 | |
294 | { |
292 | newref-> base_noderef = oldref->base_noderef; /* point down to the original node |
295 | /* create a new node reference */ |
293 | reference */ |
296 | newref = calloc (1, sizeof (noderef_t)); |
294 | |
297 | 295 | /* copy information : probably is not needed */ |
|
298 | newref->base_noderef = oldref->base_noderef; /* point down to the |
296 | /* SNIP from here ? ************************************** */ |
299 | original node reference */ |
297 | newref->pindir = oldref->pindir; |
300 | 298 | /* newref->datatype = oldref->datatype; */ |
|
301 | /* copy information : probably is not needed */ |
299 | /* get_vhdl_buswidth(newref);*/ /* sort out the VHDL bus declaration */ |
302 | /* SNIP from here ? ************************************** */ |
300 | newref->vhdltype = copy_vhdl(oldref->vhdltype,NULL); |
303 | newref->pindir = oldref->pindir; |
301 | |
304 | /* newref->datatype = oldref->datatype; */ |
302 | newref->node = oldref->node; |
305 | /* get_vhdl_buswidth(newref);*/ /* sort out the VHDL bus |
303 | /* added as forgotten 05/11/1998 */ |
306 | declaration */ |
304 | newref->orig_name = allocstr(oldref->orig_name); |
307 | newref->vhdltype = copy_vhdl (oldref->vhdltype, NULL); |
305 | newref->orig_vhdltype = copy_vhdl(oldref->orig_vhdltype,NULL); |
308 | 306 | /* end edit */ |
|
309 | newref->node = oldref->node; |
307 | |
310 | /* added as forgotten 05/11/1998 */ |
308 | |
311 | newref->orig_name = allocstr (oldref->orig_name); |
309 | /* SNIP to here ? ************************************** */ |
312 | newref->orig_vhdltype = copy_vhdl (oldref->orig_vhdltype, NULL); |
310 | /* new node refers to information on the top net if joined, |
313 | /* end edit */ |
311 | otherwise it is the sub net if aliased */ |
314 | 312 | if(topnet->how_joined == Jumpered) { |
|
315 | /* SNIP to here ? ************************************** */ |
313 | |
316 | /* new node refers to information on the top net if joined, |
314 | newref->net = topnet ; |
317 | otherwise it is the sub net if aliased */ |
315 | newref->node->routed_net = topnet; /* change routed net reference to |
318 | if (topnet->how_joined == Jumpered) |
316 | point at jumper net rather than originals */ |
319 | { |
317 | } |
320 | newref->net = topnet; |
318 | else |
321 | newref->node->routed_net = |
319 | newref->net = subnet; |
322 | topnet; /* change routed net reference to |
320 | |
323 | point at jumper net rather than originals */ |
321 | /* attach it to the net */ |
324 | } |
322 | newref->next = topnet->nodes; |
325 | else |
323 | topnet->nodes = newref; |
326 | newref->net = subnet; |
324 | |
327 | 325 | ||
328 | /* attach it to the net */ |
326 | |
329 | newref->next = topnet->nodes; |
327 | /* count nodes */ |
330 | topnet->nodes = newref; |
328 | topnet->nodecount++; |
331 | 329 | ||
332 | /* count nodes */ |
330 | oldref=oldref->next; |
333 | topnet->nodecount++; |
331 | } |
334 | 332 | } |
|
335 | oldref = oldref->next; |
333 | return 1; /* success on a plate */ |
336 | } |
334 | |
337 | } |
- | |
338 | return 1; /* success on a plate */ |
- | |
339 | } |
335 | } |
340 | 336 | ||
341 | /****************************************************************************/ |
337 | /****************************************************************************/ |
342 | /* this procedure takes a jumper apart as a result of failure */ |
338 | /* this procedure takes a jumper apart as a result of failure */ |
343 | /* it takes the subnets and links them back into the main routed net list, |
339 | /* it takes the subnets and links them back into the main routed net list, |
344 | removes the top net that was the jumper */ |
340 | removes the top net that was the jumper */ |
345 | __declspec(dllexport) int disconnect_jumper (net_t **list, net_t *jumper) |
341 | __declspec (dllexport) int disconnect_jumper(net_t ** list, |
346 | - | ||
- | 342 | net_t * jumper) |
|
- | 343 | ||
347 | { |
344 | { |
348 | net_t *first_member = jumper->subnets; |
345 | net_t * first_member = jumper->subnets; |
349 | net_t *current_member; |
346 | net_t * current_member; |
350 | net_t *previous_member = jumper; |
347 | net_t * previous_member = jumper; |
351 | net_t *next_list = jumper->next; |
348 | net_t * next_list = jumper->next; |
352 | /* at this point we have |
349 | /* at this point we have |
353 | 350 | ||
354 | previous net<-->jumper<-->next net |
351 | previous net<-->jumper<-->next net |
355 | | |
352 | | |
356 | sub1-->sub2-->sub3... |
353 | sub1-->sub2-->sub3... |
- | 354 | |
|
357 | |
355 | */ |
- | 356 | current_member = first_member; |
|
- | 357 | ||
- | 358 | if(first_member) { |
|
- | 359 | ||
- | 360 | while(current_member) { |
|
- | 361 | ||
- | 362 | current_member->next = current_member->joined_nets; /* copy next pointer from join list*/ |
|
- | 363 | current_member->prev = previous_member; |
|
- | 364 | current_member->joined_nets = NULL; |
|
- | 365 | current_member->join_parent = NULL ; /* no longer part of a jumper */ |
|
- | 366 | ||
- | 367 | previous_member->next = current_member; |
|
- | 368 | previous_member = current_member; |
|
- | 369 | Log(LOG_ERROR,"-- disconnecting '%s'\n",current_member->identifier); |
|
- | 370 | current_member = current_member->next; |
|
358 | 371 | }; |
|
- | 372 | previous_member->next = next_list; |
|
- | 373 | if(previous_member->next) |
|
359 | */ |
374 | previous_member->next->prev = previous_member; |
- | 375 | ||
- | 376 | } |
|
- | 377 | ||
- | 378 | ||
- | 379 | ||
- | 380 | /* converted to |
|
- | 381 | previous net<-->jumper<-->sub1<-->sub2<-->sub3<-->next net |
|
- | 382 | */ |
|
- | 383 | ||
- | 384 | ||
- | 385 | Log(LOG_GENERAL,"-- From jumper '%s'\n\n",jumper->identifier); |
|
- | 386 | remove_net(list,jumper); |
|
- | 387 | return 1; |
|
- | 388 | } |
|
360 | current_member = first_member; |
389 | |
361 | - | ||
362 | if (first_member) |
- | |
363 | { |
- | |
364 | while (current_member) |
- | |
365 | { |
- | |
366 | current_member->next = |
- | |
367 | current_member->joined_nets; /* copy next pointer from join list*/ |
- | |
368 | current_member->prev = previous_member; |
- | |
369 | current_member->joined_nets = NULL; |
- | |
370 | current_member->join_parent = NULL; /* no longer part of a jumper */ |
- | |
371 | - | ||
372 | previous_member->next = current_member; |
- | |
373 | previous_member = current_member; |
- | |
374 | Log ( |
- | |
375 | LOG_ERROR, |
- | |
376 | "-- disconnecting '%s'\n", |
- | |
377 | current_member->identifier); |
- | |
378 | current_member = current_member->next; |
- | |
379 | }; |
- | |
380 | previous_member->next = next_list; |
- | |
381 | if (previous_member->next) |
- | |
382 | previous_member->next->prev = previous_member; |
- | |
383 | } |
- | |
384 | - | ||
385 | /* converted to |
- | |
386 | previous net<-->jumper<-->sub1<-->sub2<-->sub3<-->next net |
- | |
387 | */ |
- | |
388 | - | ||
389 | Log (LOG_GENERAL, "-- From jumper '%s'\n\n", jumper->identifier); |
- | |
390 | remove_net (list, jumper); |
- | |
391 | return 1; |
- | |
392 | } |
390 | |
393 | 391 | /* ******************************************** */ |
|
394 | /* ******************************************** */ |
392 | |
- | 393 | ||
395 | 394 | static net_t * check_net(int * accept_nodes, |
|
- | 395 | net_t ** best_net, |
|
- | 396 | net_t * routed_net, |
|
396 | static net_t * |
397 | net_t * unrouted_net) |
397 | check_net (int *accept_nodes, net_t **best_net, net_t *routed_net, net_t *unrouted_net) |
398 | { |
- | 399 | ||
- | 400 | if (routed_net->has_external && |
|
398 | { |
401 | routed_net->nodecount >= *accept_nodes && |
399 | if (routed_net->has_external && routed_net->nodecount >= *accept_nodes && |
402 | IS_ROUTABLE(routed_net->how_routed)) { |
- | 403 | ||
400 | IS_ROUTABLE (routed_net->how_routed)) |
404 | |
401 | { |
405 | /* possibly enough nodes, but does it go the right places ?? */ |
402 | /* possibly enough nodes, but does it go the right places ?? */ |
406 | int visit_count = 0; |
403 | int visit_count = 0; |
407 | noderef_t *unrouted_nodes = unrouted_net->nodes; |
404 | noderef_t *unrouted_nodes = unrouted_net->nodes; |
408 | noderef_t *routed_nodes = routed_net->nodes; |
405 | noderef_t *routed_nodes = routed_net->nodes; |
409 | clear_routing_flags (routed_nodes); |
406 | clear_routing_flags (routed_nodes); |
410 | /* search for as yet unused but needed nodes on the unrouted net */ |
407 | /* search for as yet unused but needed nodes on the unrouted net */ |
411 | while (unrouted_nodes) { |
408 | while (unrouted_nodes) |
- | |
409 | { |
412 | if (unrouted_nodes->r_flag == 0 && |
410 | if (unrouted_nodes->r_flag == 0 && |
413 | search_net_for_socket (unrouted_nodes, routed_nodes,0) != NULL) |
411 | search_net_for_socket (unrouted_nodes, routed_nodes, 0) != NULL) |
414 | visit_count++; |
412 | visit_count++; |
415 | unrouted_nodes = unrouted_nodes->next; |
413 | unrouted_nodes = unrouted_nodes->next; |
416 | } |
414 | } |
417 | if (visit_count > *accept_nodes) { |
415 | if (visit_count > *accept_nodes) |
- | |
416 | { |
418 | *accept_nodes = visit_count; |
417 | *accept_nodes = visit_count; |
419 | *best_net = routed_net; |
418 | *best_net = routed_net; |
420 | } |
419 | } |
421 | } |
420 | } |
422 | return * best_net; |
421 | return *best_net; |
423 | } |
422 | } |
424 | |
- | 425 | ||
- | 426 | ||
- | 427 | ||
423 | 428 | /* ******************************************** */ |
|
424 | /* ******************************************** */ |
429 | /* This function tries to tidy up all nets that are currently |
425 | /* This function tries to tidy up all nets that are currently |
430 | still in the unrouted list because they are blocked |
426 | still in the unrouted list because they are blocked |
431 | The algorithm is to try and locate the routed net which visits |
427 | The algorithm is to try and locate the routed net which visits |
432 | the highest number of sockets referred to by the unrouted net |
Line 429... | Line 434... | ||
429 | and which has an external connection on it. Mark this, assign its |
434 | nodes to a jumpered net. Remove nodes used from the unrouted |
430 | nodes to a jumpered net. Remove nodes used from the unrouted |
435 | net and search again. |
431 | net and search again. |
436 | Repeat until either no jumper candidates are found or all |
432 | Repeat until either no jumper candidates are found or all |
437 | nodes on the unrouted net are used up. */ |
433 | nodes on the unrouted net are used up. */ |
438 | |
434 | - | ||
435 | __declspec(dllexport) void perform_routing_by_making_jumpers (char *Suffix) |
- | |
436 | { |
- | |
437 | int jumper_count = 1; |
- | |
438 | net_t *unrouted_net = unrouted_list; |
- | |
439 | net_t *next_net; |
- | |
440 | HowRouted_t route_type = Free; |
- | |
441 | - | ||
442 | if (!Suffix) |
- | |
443 | Suffix = ""; |
439 | |
- | 440 | __declspec (dllexport) void |
|
- | 441 | perform_routing_by_making_jumpers (char *Suffix) |
|
- | 442 | { |
|
- | 443 | int jumper_count = 1; |
|
- | 444 | net_t *unrouted_net = unrouted_list; |
|
- | 445 | net_t *next_net; |
|
- | 446 | HowRouted_t route_type = Free; |
|
- | 447 | ||
- | 448 | if (!Suffix) |
|
- | 449 | Suffix = ""; |
|
- | 450 | ||
- | 451 | ||
444 | 452 | /* firstly, set up the has_external flags on all of the nets, by checking to see if any |
|
445 | /* firstly, set up the has_external flags on all of the nets, by checking to see if any |
453 | nodes on any nets are connected to external sockets */ |
446 | nodes on any nets are connected to external sockets */ |
454 | |
447 | 455 | /* code moved to ext_nets.c |
|
448 | /* code moved to ext_nets.c |
456 | while (routed_net) |
449 | while (routed_net) |
457 | { |
450 | { |
458 | noderef_t *noderefs = routed_net->nodes; |
451 | noderef_t *noderefs = routed_net->nodes; |
459 | routed_net->has_external = 0; |
452 | routed_net->has_external = 0; |
460 | while (noderefs) |
453 | while (noderefs) |
461 | { |
454 | { |
462 | if (noderefs->node->socket->is_external) |
455 | if (noderefs->node->socket->is_external) |
463 | routed_net->has_external = 1; |
456 | routed_net->has_external = 1; |
464 | noderefs = noderefs->next; |
- | 465 | } |
|
- | 466 | routed_net = routed_net->next; |
|
- | 467 | } |
|
- | 468 | */ |
|
- | 469 | /* tidy up */ |
|
- | 470 | ||
- | 471 | while (unrouted_net) |
|
- | 472 | { /* loop through all unrouted nets */ |
|
- | 473 | int routed_ok = 1; |
|
- | 474 | int accept_nodes = 0; |
|
- | 475 | int nets_used = 0; |
|
- | 476 | int nodes_left = unrouted_net->nodecount; |
|
- | 477 | net_t *best_net; |
|
- | 478 | net_t *routed_net; |
|
- | 479 | noderef_t * unrouted_nodes; |
|
- | 480 | ||
- | 481 | ||
- | 482 | char jumper_name[JUMP_NAMLEN + 1]; |
|
- | 483 | net_t *jumper_net = NULL; |
|
- | 484 | ||
- | 485 | ||
- | 486 | ||
- | 487 | ||
- | 488 | Log (LOG_GENERAL, "\n--Looking to create net '%s' which has %d nodes\n", |
|
- | 489 | unrouted_net->identifier, nodes_left); |
|
- | 490 | /* using the routing flags to indicate a net has sucessfully visited node . |
|
- | 491 | Only clear the flags if there is actually a node list !! */ |
|
- | 492 | if (unrouted_net->nodes) |
|
- | 493 | clear_routing_flags (unrouted_net->nodes); |
|
- | 494 | ||
- | 495 | ||
- | 496 | /* iterate until a loop fails to do better, or we have jumpered all of the nodes |
|
- | 497 | we need */ |
|
- | 498 | while (routed_ok && nodes_left) { |
|
- | 499 | net_t ** list; |
|
- | 500 | int pass; |
|
- | 501 | best_net = NULL; |
|
- | 502 | accept_nodes = 0; |
|
- | 503 | for(pass = 0; pass <1 && !best_net; pass++) { |
|
- | 504 | if(pass==0) |
|
- | 505 | list = &routed_list; |
|
- | 506 | else |
|
- | 507 | list = &named_list; |
|
- | 508 | /* check for FIX_LOCATION pins as these are most important |
|
- | 509 | In this case, the best_net is one that can be connected to the FIX_LOCATION pin |
|
- | 510 | because it is not yet in use */ |
|
- | 511 | unrouted_nodes = unrouted_net->nodes; |
|
- | 512 | /* scan through until we find an unrouted node that has no routing flag set */ |
|
- | 513 | while(unrouted_nodes && !best_net ) { |
|
- | 514 | if (unrouted_nodes -> r_flag == 0) { |
|
- | 515 | net_t * poss_routed_net = unrouted_nodes->node->routed_net; |
|
- | 516 | if (poss_routed_net && |
|
- | 517 | poss_routed_net->list_ref == list) { |
|
- | 518 | if (level & 2) |
|
- | 519 | { |
|
- | 520 | Log (LOG_GENERAL, "\n-- pass %d checking net '%s'\n",pass, |
|
- | 521 | poss_routed_net->identifier); |
|
- | 522 | } |
|
- | 523 | /* is routed net still available on the routed list ? */ |
|
- | 524 | /* && poss_routed_net->has_fix_location) */ /* only fix_location nets on pass 1, then all nets */ |
|
- | 525 | check_net(&accept_nodes, |
|
- | 526 | &best_net, |
|
- | 527 | poss_routed_net, /* ???? was routed_net . no sense here !! */ |
|
- | 528 | unrouted_net) ; |
|
457 | noderefs = noderefs->next; |
529 | } |
- | 530 | } |
|
458 | } |
531 | unrouted_nodes = unrouted_nodes->next; |
459 | routed_net = routed_net->next; |
532 | } |
- | 533 | if ((level & 2) && best_net) |
|
- | 534 | { |
|
- | 535 | Log (LOG_GENERAL, "-- Phase 1 search Found as best match net '%s' with %d corresponding nodes\n", |
|
- | 536 | best_net->identifier, accept_nodes); |
|
- | 537 | } |
|
- | 538 | ||
- | 539 | if(!best_net) { |
|
- | 540 | /* check for any position to jumper if there are no FIX_LOCATION pins |
|
- | 541 | Now, search simply for any useful net, and try the one with the most |
|
- | 542 | sockets visited */ |
|
- | 543 | ||
- | 544 | routed_net = *list; |
|
- | 545 | accept_nodes = 0; |
|
- | 546 | while (routed_net) { |
|
- | 547 | if (level & 2) |
|
- | 548 | Log (LOG_GENERAL, "\n-- pass %d generally checking net '%s'\n",pass, |
|
- | 549 | routed_net->identifier); |
|
- | 550 | check_net(&accept_nodes, |
|
- | 551 | &best_net, |
|
- | 552 | routed_net, |
|
- | 553 | unrouted_net) ; |
|
- | 554 | ||
- | 555 | routed_net = routed_net->next; |
|
- | 556 | } |
|
- | 557 | if ((level & 2) && best_net) |
|
- | 558 | Log (LOG_GENERAL, "-- Phase 2 search Found as best match net '%s' with %d corresponding nodes\n", |
|
- | 559 | best_net->identifier, accept_nodes); |
|
- | 560 | } |
|
460 | } |
561 | } |
- | 562 | ||
- | 563 | if (best_net) |
|
- | 564 | { |
|
- | 565 | Log (LOG_GENERAL, "-- Found as best match net '%s' with %d corresponding nodes\n", |
|
- | 566 | best_net->identifier, accept_nodes); |
|
- | 567 | nodes_left -= accept_nodes; /* Count down how many nodes left to go */ |
|
- | 568 | ||
- | 569 | { |
|
- | 570 | noderef_t *unrouted_nodes = unrouted_net->nodes; |
|
- | 571 | clear_routing_flags (best_net->nodes); |
|
- | 572 | while (unrouted_nodes) |
|
- | 573 | { |
|
- | 574 | if (search_net_for_socket (unrouted_nodes, best_net->nodes,0) != NULL) |
|
- | 575 | { |
|
- | 576 | unrouted_nodes->r_flag = 1; |
|
- | 577 | } |
|
- | 578 | ||
- | 579 | /* when all flags on unrouted nets go to '1' then |
|
- | 580 | we have finished the jumpering */ |
|
- | 581 | if (level & 2) |
|
- | 582 | Log (LOG_GENERAL, "-- flag on %s(%s) is %d\n", unrouted_nodes->node->socket->identifier, |
|
- | 583 | unrouted_nodes->node->identifier, unrouted_nodes->r_flag); |
|
- | 584 | unrouted_nodes = unrouted_nodes->next; |
|
- | 585 | } |
|
461 | */ |
586 | } |
462 | /* tidy up */ |
587 | |
463 | - | ||
464 | while (unrouted_net) |
- | |
465 | { /* loop through all unrouted nets */ |
- | |
466 | int routed_ok = 1; |
- | |
467 | int accept_nodes = 0; |
- | |
468 | int nets_used = 0; |
- | |
469 | int nodes_left = unrouted_net->nodecount; |
- | |
470 | net_t *best_net; |
- | |
471 | net_t *routed_net; |
- | |
472 | noderef_t *unrouted_nodes; |
- | |
473 | - | ||
474 | char jumper_name[JUMP_NAMLEN + 1]; |
- | |
475 | net_t *jumper_net = NULL; |
- | |
476 | - | ||
477 | Log ( |
- | |
478 | LOG_GENERAL, |
- | |
479 | "\n--Looking to create net '%s' which has %d nodes\n", |
- | |
480 | unrouted_net->identifier, |
- | |
481 | nodes_left); |
- | |
482 | /* using the routing flags to indicate a net has sucessfully visited node . |
- | |
483 | Only clear the flags if there is actually a node list !! */ |
- | |
484 | if (unrouted_net->nodes) |
- | |
485 | clear_routing_flags (unrouted_net->nodes); |
- | |
486 | - | ||
487 | /* iterate until a loop fails to do better, or we have jumpered all of the |
- | |
488 | nodes we need */ |
- | |
489 | while (routed_ok && nodes_left) |
- | |
490 | { |
- | |
491 | net_t **list; |
- | |
492 | int pass; |
- | |
493 | best_net = NULL; |
- | |
494 | accept_nodes = 0; |
- | |
495 | for (pass = 0; pass < 1 && !best_net; pass++) |
- | |
496 | { |
- | |
497 | if (pass == 0) |
- | |
498 | list = &routed_list; |
- | |
499 | else |
- | |
500 | list = &named_list; |
- | |
501 | /* check for FIX_LOCATION pins as these are most important |
- | |
502 | In this case, the best_net is one that can be connected to |
- | |
503 | the FIX_LOCATION pin because it is not yet in use */ |
- | |
504 | unrouted_nodes = unrouted_net->nodes; |
- | |
505 | /* scan through until we find an unrouted node that has no |
- | |
506 | * routing flag set */ |
- | |
507 | while (unrouted_nodes && !best_net) |
- | |
508 | { |
- | |
509 | if (unrouted_nodes->r_flag == 0) |
- | |
510 | { |
- | |
511 | net_t *poss_routed_net = |
- | |
512 | unrouted_nodes->node->routed_net; |
- | |
513 | if (poss_routed_net && |
- | |
514 | poss_routed_net->list_ref == list) |
- | |
515 | { |
- | |
516 | if (level & 2) |
- | |
517 | { |
- | |
518 | Log ( |
- | |
519 | LOG_GENERAL, |
- | |
520 | "\n-- pass %d checking " |
- | |
521 | "net '%s'\n", |
- | |
522 | pass, |
- | |
523 | poss_routed_net |
- | |
524 | ->identifier); |
- | |
525 | } |
- | |
526 | /* is routed net still available on the |
- | |
527 | * routed list ? */ |
- | |
528 | /* && |
- | |
529 | * poss_routed_net->has_fix_location) |
- | |
530 | */ /* only fix_location nets on pass 1, then all nets */ |
- | |
531 | check_net ( |
- | |
532 | &accept_nodes, |
- | |
533 | &best_net, |
- | |
534 | poss_routed_net, /* ???? was |
- | |
535 | routed_net . no |
- | |
536 | sense here !! |
- | |
537 | */ |
- | |
538 | unrouted_net); |
- | |
539 | } |
- | |
540 | } |
- | |
541 | unrouted_nodes = unrouted_nodes->next; |
- | |
542 | } |
- | |
543 | if ((level & 2) && best_net) |
- | |
544 | { |
- | |
545 | Log ( |
- | |
546 | LOG_GENERAL, |
- | |
547 | "-- Phase 1 search Found as best match net '%s' " |
- | |
548 | "with %d corresponding nodes\n", |
- | |
549 | best_net->identifier, |
- | |
550 | accept_nodes); |
- | |
551 | } |
- | |
552 | - | ||
553 | if (!best_net) |
- | |
554 | { |
- | |
555 | /* check for any position to jumper if there are no |
- | |
556 | FIX_LOCATION pins Now, search simply for any useful |
- | |
557 | net, and try the one with the most sockets visited */ |
- | |
558 | - | ||
559 | routed_net = *list; |
- | |
560 | accept_nodes = 0; |
- | |
561 | while (routed_net) |
- | |
562 | { |
- | |
563 | if (level & 2) |
- | |
564 | Log ( |
- | |
565 | LOG_GENERAL, |
- | |
566 | "\n-- pass %d generally checking " |
- | |
567 | "net '%s'\n", |
- | |
568 | pass, |
- | |
569 | routed_net->identifier); |
- | |
570 | check_net ( |
- | |
571 | &accept_nodes, |
- | |
572 | &best_net, |
- | |
573 | routed_net, |
- | |
574 | unrouted_net); |
- | |
575 | - | ||
576 | routed_net = routed_net->next; |
- | |
577 | } |
- | |
578 | if ((level & 2) && best_net) |
- | |
579 | Log ( |
- | |
580 | LOG_GENERAL, |
- | |
581 | "-- Phase 2 search Found as best match " |
- | |
582 | "net '%s' with %d corresponding nodes\n", |
- | |
583 | best_net->identifier, |
- | |
584 | accept_nodes); |
- | |
585 | } |
- | |
586 | } |
- | |
587 | - | ||
588 | if (best_net) |
- | |
589 | { |
- | |
590 | Log ( |
- | |
591 | LOG_GENERAL, |
- | |
592 | "-- Found as best match net '%s' with %d corresponding " |
- | |
593 | "nodes\n", |
- | |
594 | best_net->identifier, |
- | |
595 | accept_nodes); |
- | |
596 | nodes_left -= |
- | |
597 | accept_nodes; /* Count down how many nodes left to go */ |
- | |
598 | - | ||
599 | { |
- | |
600 | noderef_t *unrouted_nodes = unrouted_net->nodes; |
- | |
601 | clear_routing_flags (best_net->nodes); |
- | |
602 | while (unrouted_nodes) |
- | |
603 | { |
- | |
604 | if (search_net_for_socket ( |
- | |
605 | unrouted_nodes, best_net->nodes, 0) != |
- | |
606 | NULL) |
- | |
607 | { |
- | |
608 | unrouted_nodes->r_flag = 1; |
- | |
609 | } |
- | |
610 | - | ||
611 | /* when all flags on unrouted nets go to '1' |
- | |
612 | then we have finished the jumpering */ |
- | |
613 | if (level & 2) |
- | |
614 | Log ( |
- | |
615 | LOG_GENERAL, |
- | |
616 | "-- flag on %s(%s) is %d\n", |
- | |
617 | unrouted_nodes->node->socket |
- | |
618 | ->identifier, |
- | |
619 | unrouted_nodes->node->identifier, |
- | |
620 | unrouted_nodes->r_flag); |
- | |
621 | unrouted_nodes = unrouted_nodes->next; |
- | |
622 | } |
- | |
623 | } |
- | |
624 | 588 | if (nets_used++ == 0 && nodes_left == 0) { |
|
625 | if (nets_used++ == 0 && nodes_left == 0) |
- | |
626 | { |
- | |
627 | /* we seem to have found a complete path already with |
- | |
628 | all the nodes on it. the user is obviously using |
- | |
629 | 'jumper' before 'route' */ |
- | |
630 | if (level & 2) |
- | |
631 | Log ( |
- | |
632 | LOG_GENERAL, |
- | |
633 | "-- This net contains all nodes " |
- | |
634 | "requested, simply connecting\n\n"); |
- | |
635 | jumper_net = best_net; |
- | |
636 | route_type = By_Net; |
- | |
637 | } |
- | |
638 | else |
- | |
639 | { |
- | |
640 | route_type = By_Jumpering; |
- | |
641 | /* try hard to create a unique jumper ID */ |
- | |
642 | while (!jumper_net) |
- | |
643 | { |
- | |
644 | sprintf ( |
- | |
645 | jumper_name, |
- | |
646 | JUMP_FMT, |
- | |
647 | Suffix, |
- | |
648 | jumper_count++); |
- | |
649 | jumper_net = find_net ( |
- | |
650 | &routed_list, Ident, jumper_name, Search); |
- | |
651 | /* if it is not found then the name proposed is |
- | |
652 | * unique */ |
- | |
653 | if (!jumper_net) |
- | |
654 | { |
- | |
655 | jumper_net = find_net ( |
- | |
656 | &routed_list, |
- | |
657 | Ident, |
- | |
658 | jumper_name, |
- | |
659 | Create); |
- | |
660 | /* |
- | |
661 | Log |
- | |
662 | (LOG_GENERAL, "-- Creating jumper |
- | |
663 | %s\n", jumper_net->identifier); |
- | |
664 | */ |
- | |
665 | jumper_net->how_joined = Jumpered; |
- | |
666 | break; |
- | |
667 | } |
- | |
668 | else |
- | |
669 | jumper_net = |
- | |
670 | NULL; /* if found already, it |
- | |
671 | should not terminate the |
- | |
672 | loop */ |
- | |
673 | } |
- | |
674 | Log ( |
- | |
675 | LOG_GENERAL, |
- | |
676 | "-- Jumpering %s to net %s (nodes_left=%d)\n", |
- | |
677 | jumper_net->identifier, |
- | |
678 | best_net->identifier, |
- | |
679 | nodes_left); |
- | |
680 | /* mark the used nodes by setting the r_flag on the |
- | |
681 | * used unrouted nodes */ |
- | |
682 | - | ||
683 | /* find the first node that is connected to an external |
- | |
684 | * pin on the best_net */ |
- | |
685 | /* record this as the external node */ |
- | |
686 | - | ||
687 | { |
- | |
688 | noderef_t *routed_nodes = best_net->nodes; |
- | |
689 | while (routed_nodes) |
- | |
690 | { |
- | |
691 | if (routed_nodes->node->socket |
- | |
692 | ->is_external) |
- | |
693 | { |
- | |
694 | best_net->external_node = |
- | |
695 | routed_nodes->node; |
- | |
696 | break; |
- | |
697 | } |
- | |
698 | routed_nodes = routed_nodes->next; |
- | |
699 | } |
- | |
700 | } |
- | |
701 | - | ||
702 | /* make the jumper */ |
- | |
703 | transfer_net_to_subnet ( |
- | |
704 | &routed_list, jumper_net, best_net); |
- | |
705 | routed_ok = 1; |
- | |
706 | } |
- | |
707 | } |
- | |
708 | else |
- | |
709 | { |
- | |
710 | routed_ok = 0; |
- | |
711 | Log ( |
- | |
712 | LOG_ERROR, |
- | |
713 | "-- Error : insufficient/no jumperable nets free\n" |
- | |
714 | "-- to create net '%s' which requires %d more nodes\n", |
- | |
715 | unrouted_net->identifier, |
- | |
716 | nodes_left); |
- | |
717 | } |
- | |
718 | } |
- | |
719 | next_net = unrouted_net->next; |
589 | |
- | 590 | /* we seem to have found a complete path already with all the nodes on |
|
- | 591 | it. the user is obviously using 'jumper' before 'route' */ |
|
720 | 592 | if (level & 2) |
|
- | 593 | Log (LOG_GENERAL, "-- This net contains all nodes requested, simply connecting\n\n"); |
|
- | 594 | jumper_net = best_net; |
|
- | 595 | route_type = By_Net; |
|
721 | if (routed_ok) |
596 | } |
- | 597 | else |
|
- | 598 | { |
|
- | 599 | route_type = By_Jumpering; |
|
- | 600 | /* try hard to create a unique jumper ID */ |
|
- | 601 | while (!jumper_net) { |
|
722 | { |
602 | sprintf (jumper_name, JUMP_FMT, Suffix, jumper_count++); |
723 | combine_routed_and_unrouted (jumper_net, unrouted_net); |
603 | jumper_net = find_net (&routed_list, Ident, jumper_name, Search); |
724 | transfer_net_to_named (&routed_list, jumper_net); /* jumpers are in |
604 | /* if it is not found then the name proposed is unique */ |
725 | routed list */ |
605 | if (!jumper_net) { |
726 | jumper_net->how_routed = route_type; |
606 | jumper_net = find_net (&routed_list, Ident, jumper_name, Create); |
- | 607 | /* |
|
- | 608 | Log (LOG_GENERAL, "-- Creating jumper %s\n", jumper_net->identifier); |
|
- | 609 | */ |
|
- | 610 | jumper_net->how_joined = Jumpered; |
|
727 | next_net = remove_net (&unrouted_list, unrouted_net); |
611 | break; |
728 | } |
612 | } |
729 | else |
613 | else |
730 | { |
614 | jumper_net = NULL; /* if found already, it should not terminate |
731 | /* Failure to complete, so remove the partially completed jumper net |
615 | the loop */ |
- | 616 | ||
732 | * from the list */ |
617 | } |
- | 618 | Log (LOG_GENERAL, "-- Jumpering %s to net %s (nodes_left=%d)\n", |
|
- | 619 | jumper_net->identifier, best_net->identifier,nodes_left); |
|
- | 620 | /* mark the used nodes by setting the r_flag on the used unrouted nodes */ |
|
- | 621 | ||
- | 622 | ||
- | 623 | /* find the first node that is connected to an external pin on the best_net */ |
|
- | 624 | /* record this as the external node */ |
|
- | 625 | ||
733 | if (jumper_net) |
626 | { |
- | 627 | noderef_t *routed_nodes = best_net->nodes; |
|
- | 628 | while (routed_nodes) { |
|
- | 629 | if (routed_nodes->node->socket->is_external) { |
|
- | 630 | best_net->external_node = routed_nodes->node; |
|
734 | { |
631 | break; |
735 | Log ( |
632 | } |
736 | LOG_ERROR, |
633 | routed_nodes = routed_nodes->next; |
- | 634 | } |
|
- | 635 | } |
|
- | 636 | ||
- | 637 | /* make the jumper */ |
|
737 | "-- failure : disconnecting partially completed jumper\n"); |
638 | transfer_net_to_subnet (&routed_list, jumper_net, best_net); |
738 | disconnect_jumper (&routed_list, jumper_net); |
639 | routed_ok = 1; |
739 | } |
640 | } |
- | 641 | } |
|
- | 642 | else { |
|
- | 643 | routed_ok = 0; |
|
- | 644 | Log (LOG_ERROR, "-- Error : insufficient/no jumperable nets free\n" |
|
- | 645 | "-- to create net '%s' which requires %d more nodes\n", |
|
- | 646 | unrouted_net->identifier, nodes_left); |
|
- | 647 | } |
|
- | 648 | } |
|
- | 649 | next_net = unrouted_net->next; |
|
- | 650 | ||
- | 651 | if (routed_ok) { |
|
- | 652 | combine_routed_and_unrouted (jumper_net, unrouted_net); |
|
- | 653 | transfer_net_to_named (&routed_list, jumper_net); /* jumpers are in routed list */ |
|
- | 654 | jumper_net->how_routed = route_type; |
|
- | 655 | next_net = remove_net (&unrouted_list, unrouted_net); |
|
- | 656 | } |
|
- | 657 | else { |
|
- | 658 | /* Failure to complete, so remove the partially completed jumper net from the list */ |
|
- | 659 | if(jumper_net) |
|
- | 660 | { |
|
- | 661 | Log(LOG_ERROR,"-- failure : disconnecting partially completed jumper\n"); |
|
- | 662 | disconnect_jumper( &routed_list,jumper_net); |
|
- | 663 | } |
|
- | 664 | } |
|
- | 665 | ||
- | 666 | unrouted_net = next_net; |
|
- | 667 | } |
|
- | 668 | count_nets ("After using new paths created by jumpers"); |
|
- | 669 | ||
740 | } |
670 | |
741 | - | ||
742 | unrouted_net = next_net; |
- | |
743 | } |
- | |
744 | count_nets ("After using new paths created by jumpers"); |
671 | } |
745 | } |
672 | |
- | 673 | ||
746 | 674 | /* ******************************************** */ |
|
- | 675 | __declspec (dllexport) void |
|
747 | /* ******************************************** */ |
676 | perform_jumpering (char *Suffix) |
748 | __declspec(dllexport) void perform_jumpering (char *Suffix) |
677 | { |
749 | { |
- | |
750 | count_nets ("Before jumper creation"); |
- | |
751 | /* remove any connections we can already make */ |
- | |
752 | /* perform_routing_by_exact_path (); */ |
678 | |
753 | 679 | count_nets ("Before jumper creation"); |
|
- | 680 | /* remove any connections we can already make */ |
|
754 | /* make the jumpers */ |
681 | /* perform_routing_by_exact_path (); */ |
755 | perform_routing_by_making_jumpers (Suffix); |
682 | |
756 | 683 | /* make the jumpers */ |
|
757 | /* then use the jumpers */ |
684 | perform_routing_by_making_jumpers (Suffix); |
758 | /* perform_routing_by_exact_path ();*/ |
685 | |
- | 686 | /* then use the jumpers */ |
|
- | 687 | /* perform_routing_by_exact_path ();*/ |
|
- | 688 | ||
759 | 689 | /* then use the jumpers */ |
|
760 | /* then use the jumpers */ |
690 | /* perform_routing_by_path (); */ |
761 | /* perform_routing_by_path (); */ |
691 | } |
762 | } |
692 | /* ******************************************** */ |
763 | /* ******************************************** */ |
693 | |
764 | 694 | /* try to join all the pins seen on ID1 to ID2 */ |
|
765 | /* try to join all the pins seen on ID1 to ID2 */ |
695 | __declspec (dllexport) void create_all_jumpers(char * ID1,char * ID2) { |
766 | __declspec(dllexport) void create_all_jumpers (char *ID1, char *ID2) |
- | |
767 | { |
696 | socket_t * ID1_skt, * ID2_skt; |
768 | socket_t *ID1_skt, *ID2_skt; |
697 | node_t * ID1_node, * ID2_node; |
769 | node_t *ID1_node, *ID2_node; |
698 | net_t * jumper_net ,* ID1_net, * ID2_net; |
770 | net_t *jumper_net, *ID1_net, *ID2_net; |
699 | char rootname[MAXIDLEN]; |
771 | char rootname[MAXIDLEN]; |
700 | char * append_point; |
772 | char *append_point; |
701 | ID1_skt = find_socket(Ident,ID1,Search,&socket_head); |
773 | ID1_skt = find_socket (Ident, ID1, Search, &socket_head); |
702 | ID2_skt = find_socket(Ident,ID2,Search,&socket_head); |
774 | ID2_skt = find_socket (Ident, ID2, Search, &socket_head); |
703 | if(!ID1_skt) { |
- | 704 | Log(LOG_ERROR,"# ERROR : CONNECTION cannot find socket '%s'\n",ID1); |
|
- | 705 | return; |
|
775 | if (!ID1_skt) |
706 | } |
- | 707 | if(!ID2_skt) { |
|
776 | { |
708 | Log(LOG_ERROR,"# ERROR : CONNECTION cannot find socket '%s'\n",ID2); |
777 | Log (LOG_ERROR, "# ERROR : CONNECTION cannot find socket '%s'\n", ID1); |
709 | return; |
778 | return; |
710 | } |
- | 711 | ||
- | 712 | sprintf(rootname,"cn_%s_%s_",ID1_skt->identifier,ID2_skt->identifier); |
|
- | 713 | Log(LOG_GENERAL,"-- Creating CONNECTION '%s'\n",rootname); |
|
- | 714 | ||
- | 715 | append_point=rootname+strlen(rootname); /* where to append the final pin ID */ |
|
- | 716 | /* for each node on the first chip, try and find the net that it is on in |
|
- | 717 | the routed list, and jumper it to the net that is on the same pin ID on the second chip. */ |
|
- | 718 | ||
- | 719 | ID1_node = ID1_skt->nodes; |
|
- | 720 | while(ID1_node) { |
|
- | 721 | if(ID1_node->net && ID1_node->net->list_ref == &routed_list) { |
|
- | 722 | /* find the highest level of jumper and join it */ |
|
779 | } |
723 | ID1_net = ID1_node->net; |
- | 724 | while (ID1_net->join_parent) |
|
- | 725 | ID1_net=ID1_net->join_parent; |
|
780 | if (!ID2_skt) |
726 | |
- | 727 | ID2_node = find_node(ID2_skt,Ident,ID1_node->identifier,Search); |
|
- | 728 | if(ID2_node) { |
|
- | 729 | if(ID2_node->net && ID2_node->net->list_ref == &routed_list) { |
|
781 | { |
730 | /* find the highest level of jumper and join it */ |
782 | Log (LOG_ERROR, "# ERROR : CONNECTION cannot find socket '%s'\n", ID2); |
731 | ID2_net = ID2_node->net; |
- | 732 | while (ID2_net->join_parent) |
|
- | 733 | ID2_net=ID2_net->join_parent; |
|
783 | return; |
734 | |
- | 735 | ||
- | 736 | /* we now have a matched pair of nodes for which we have to find the nets. |
|
- | 737 | If the nets are both on the list of routed net, create a named jumper between them */ |
|
- | 738 | ||
784 | } |
739 | |
785 | - | ||
786 | sprintf (rootname, "cn_%s_%s_", ID1_skt->identifier, ID2_skt->identifier); |
- | |
787 | Log (LOG_GENERAL, "-- Creating CONNECTION '%s'\n", rootname); |
740 | |
788 | 741 | strcpy(append_point,ID1_node->identifier); /* create the totla new net name */ |
|
- | 742 | /* |
|
- | 743 | printf("Can make jumper '%s'\n",rootname); |
|
- | 744 | */ |
|
- | 745 | ||
789 | append_point = rootname + strlen (rootname); /* where to append the final pin ID */ |
746 | jumper_net = find_net (&routed_list, Ident, rootname, Create); |
- | 747 | jumper_net->how_joined = Jumpered; |
|
- | 748 | if (transfer_net_to_subnet(&routed_list,jumper_net, ID1_net)) |
|
- | 749 | ID1_node->net->external_node = ID1_node; |
|
790 | /* for each node on the first chip, try and find the net that it is on in |
750 | if (transfer_net_to_subnet(&routed_list,jumper_net, ID2_net)) |
- | 751 | ID2_node->net->external_node = ID2_node; |
|
- | 752 | ||
791 | the routed list, and jumper it to the net that is on the same pin ID on the second |
753 | } |
- | 754 | else |
|
- | 755 | Log(LOG_ERROR,"-- Warning : Node '%s(%s)' does not appear on a routed net\n", |
|
- | 756 | ID2_skt->identifier,ID2_node->identifier); |
|
- | 757 | } |
|
- | 758 | else |
|
- | 759 | Log(LOG_ERROR,"-- Warning : Cannot locate pin '%s' on socket '%s'\n", |
|
- | 760 | ID1_node->identifier,ID2_skt->identifier); |
|
- | 761 | } |
|
- | 762 | else |
|
- | 763 | Log(LOG_ERROR,"-- Warning : Node '%s(%s)' does not appear on a routed net\n", |
|
- | 764 | ID1_skt->identifier,ID1_node->identifier); |
|
- | 765 | ID1_node=ID1_node->sktnext; /* move along the socket pins */ |
|
- | 766 | } |
|
- | 767 | ||
- | 768 | ||
- | 769 | ||
792 | chip. */ |
770 | |
793 | - | ||
794 | ID1_node = ID1_skt->nodes; |
- | |
795 | while (ID1_node) |
- | |
796 | { |
- | |
797 | if (ID1_node->net && ID1_node->net->list_ref == &routed_list) |
- | |
798 | { |
- | |
799 | /* find the highest level of jumper and join it */ |
- | |
800 | ID1_net = ID1_node->net; |
- | |
801 | while (ID1_net->join_parent) |
- | |
802 | ID1_net = ID1_net->join_parent; |
771 | |
803 | - | ||
804 | ID2_node = find_node (ID2_skt, Ident, ID1_node->identifier, Search); |
- | |
805 | if (ID2_node) |
- | |
806 | { |
- | |
807 | if (ID2_node->net && ID2_node->net->list_ref == &routed_list) |
- | |
808 | { |
- | |
809 | /* find the highest level of jumper and join it */ |
- | |
810 | ID2_net = ID2_node->net; |
- | |
811 | while (ID2_net->join_parent) |
- | |
812 | ID2_net = ID2_net->join_parent; |
- | |
813 | - | ||
814 | /* we now have a matched pair of nodes for which we |
- | |
815 | have to find the nets. |
- | |
816 | If the nets are both on the list of routed net, create |
- | |
817 | a named jumper between them */ |
- | |
818 | - | ||
819 | strcpy ( |
- | |
820 | append_point, |
- | |
821 | ID1_node->identifier); /* create the totla new net |
- | |
822 | name */ |
- | |
823 | /* |
- | |
824 | printf("Can make jumper '%s'\n",rootname); |
- | |
825 | */ |
- | |
826 | - | ||
827 | jumper_net = |
- | |
828 | find_net (&routed_list, Ident, rootname, Create); |
- | |
829 | jumper_net->how_joined = Jumpered; |
- | |
830 | if (transfer_net_to_subnet ( |
- | |
831 | &routed_list, jumper_net, ID1_net)) |
- | |
832 | ID1_node->net->external_node = ID1_node; |
- | |
833 | if (transfer_net_to_subnet ( |
- | |
834 | &routed_list, jumper_net, ID2_net)) |
- | |
835 | ID2_node->net->external_node = ID2_node; |
- | |
836 | } |
- | |
837 | else |
- | |
838 | Log ( |
- | |
839 | LOG_ERROR, |
- | |
840 | "-- Warning : Node '%s(%s)' does not appear on a " |
- | |
841 | "routed net\n", |
- | |
842 | ID2_skt->identifier, |
- | |
843 | ID2_node->identifier); |
- | |
844 | } |
- | |
845 | else |
- | |
846 | Log ( |
- | |
847 | LOG_ERROR, |
- | |
848 | "-- Warning : Cannot locate pin '%s' on socket '%s'\n", |
- | |
849 | ID1_node->identifier, |
- | |
850 | ID2_skt->identifier); |
- | |
851 | } |
- | |
852 | else |
- | |
853 | Log ( |
- | |
854 | LOG_ERROR, |
- | |
855 | "-- Warning : Node '%s(%s)' does not appear on a routed net\n", |
- | |
856 | ID1_skt->identifier, |
- | |
857 | ID1_node->identifier); |
- | |
858 | ID1_node = ID1_node->sktnext; /* move along the socket pins */ |
- | |
859 | } |
772 | } |
860 | } |
773 | |
861 | 774 | /*******************************************************/ |
|
862 | /*******************************************************/ |
775 | |
863 | 776 | void create_vhdl_connections(void) |
|
864 | void create_vhdl_connections (void) |
777 | { |
865 | { |
778 | net_t * top_net; |
866 | net_t *top_net; |
779 | net_t * subnet; |
867 | net_t *subnet; |
780 | /* assume that create_unrouted_list has already happened */ |
868 | /* assume that create_unrouted_list has already happened */ |
781 | top_net = unrouted_list; |
869 | top_net = unrouted_list; |
782 | while(top_net) |
870 | while (top_net) |
783 | { |
871 | { |
784 | if (top_net->vhdl_connect_net) |
872 | if (top_net->vhdl_connect_net) |
785 | { |
873 | { |
786 | printf("root net found '%s'\n",top_net->name); |
874 | printf ("root net found '%s'\n", top_net->name); |
787 | if(top_net->how_joined != NotJoined) |
875 | if (top_net->how_joined != NotJoined) |
788 | { |
876 | { |
- | |
877 | Log ( |
- | |
878 | LOG_ERROR, |
789 | Log(LOG_ERROR,"# Warning : %s net '%s' already exists, net is being extended from %d nodes\n", |
879 | "# Warning : %s net '%s' already exists, net is being " |
- | |
880 | "extended from %d nodes\n", |
790 | top_net->how_joined == Jumpered ? "Jumpered" : "Aliased", |
881 | top_net->how_joined == Jumpered ? "Jumpered" : "Aliased", |
- | |
882 | top_net->identifier, |
791 | top_net->identifier,top_net->nodecount); |
883 | top_net->nodecount); |
792 | /* if the net is already in existence, it will have nodes */ |
884 | /* if the net is already in existence, it will have nodes */ |
793 | } |
885 | } |
794 | top_net->how_joined = Jumpered; |
886 | top_net->how_joined = Jumpered; |
- | |
887 | transfer_net_to_subnet ( |
795 | transfer_net_to_subnet(&unrouted_list, top_net, top_net->vhdl_connect_net); |
888 | &unrouted_list, top_net, top_net->vhdl_connect_net); |
796 | } |
889 | } |
797 | top_net = top_net -> next; |
890 | top_net = top_net->next; |
798 | } |
891 | } |
799 | } |