Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | mjames | 1 | /* $Id: equivalent.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $ */ |
11 | mjames | 2 | /* |
2 | mjames | 3 | * $Log: equivalent.c,v $ |
4 | * Revision 1.1.1.1 2003/11/04 23:34:57 mjames |
||
5 | * Imported into local repositrory |
||
6 | * |
||
7 | * Revision 1.9 2003/01/02 21:37:15 mjames |
||
8 | * Experiment on creating NOT_ROUTABLE_H and NOT_ROUTABLE_L |
||
9 | * properties on the nets so that pin jumpers can be made without a problem. |
||
10 | * |
||
11 | * Still need to sort out pin assignments made to these not_routable nets |
||
12 | * which will become legal in some cases so that pullups and pulldown |
||
13 | * pins can be used on the FPGA. |
||
14 | * |
||
15 | * Revision 1.8 2002/09/09 10:26:56 mjames |
||
16 | * Removed set generic range and replaced it with a set generic value command |
||
17 | * that takes both integers and ranges. |
||
18 | * |
||
19 | * Revision 1.7 2002/01/15 12:36:22 mjames |
||
20 | * DLL declarations put in, |
||
21 | * |
||
22 | * #ident used |
||
23 | * |
||
24 | * Revision 1.6 2001/11/01 11:06:49 mjames |
||
25 | * Simplified code for connection of equivalent node sets to components |
||
26 | * |
||
27 | * Revision 1.5 2001/10/31 22:20:03 mjames |
||
28 | * Tidying up problematical comments caused by CVS |
||
29 | * 'intelligent' comment guessing |
||
30 | * |
||
31 | */ |
||
11 | mjames | 32 | |
33 | |||
2 | mjames | 34 | /* This file handles equivalent pins , being passthroughs or |
35 | low value resistors which can be regarded as passthrough jumpers */ |
||
11 | mjames | 36 | |
2 | mjames | 37 | /* Extracted from ACFREAD syntax : pin equivalences within a chip or template |
11 | mjames | 38 | declaration |
39 | |||
40 | pin_equivalence : EQUIVALENT LBRK { curr_equiv_list = begin_equivalent_pins(); } |
||
41 | equivalent_pins |
||
42 | RBRK end_item { check_equivalent_pins(current_chip,curr_equiv_list); } |
||
2 | mjames | 43 | ; |
11 | mjames | 44 | |
2 | mjames | 45 | equivalent_pins : equivalent_pin SEMI equivalent_pins |
46 | | equivalent_pin |
||
11 | mjames | 47 | | |
48 | ; |
||
49 | |||
2 | mjames | 50 | equivalent_pin : astring { add_equivalent_pin( current_chip,curr_equiv_list,$1); }; |
51 | |||
52 | in2 : input_pin = a1; |
||
53 | in3 : input_pin = f1; |
||
54 | |||
55 | e.g. EQUIVALENT ( a1;f1); |
||
56 | |||
57 | */ |
||
58 | |||
59 | /* we approach the storage of nodes with caution , deferring the |
||
60 | adding of information until it is correct */ |
||
61 | |||
11 | mjames | 62 | #include <stdio.h> |
63 | #include <string.h> |
||
64 | #include <stdlib.h> |
||
65 | #include <ctype.h> |
||
2 | mjames | 66 | |
11 | mjames | 67 | #include "vertcl_main.h" |
2 | mjames | 68 | #include "expression.h" |
69 | #include "generic.h" |
||
11 | mjames | 70 | #include "database.h" |
71 | #include "cmdparse.h" |
||
72 | #include "cmdlog.h" |
||
73 | #include "printout.h" |
||
74 | #include "equivalent.h" |
||
2 | mjames | 75 | #include "jumpering.h" |
76 | |||
77 | |||
11 | mjames | 78 | #ident "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/equivalent.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $" |
2 | mjames | 79 | |
11 | mjames | 80 | |
2 | mjames | 81 | /********************************************************************/ |
82 | /* this function starts to create a list of equivalent pins */ |
||
83 | /********************************************************************/ |
||
11 | mjames | 84 | equivalent_node_set_t * begin_equivalent_pins( void) { |
85 | equivalent_node_set_t * node_set; |
||
86 | node_set = calloc(1,sizeof ( equivalent_node_set_t )); |
||
87 | return node_set; |
||
88 | } |
||
2 | mjames | 89 | |
11 | mjames | 90 | |
91 | |||
2 | mjames | 92 | /********************************************************************/ |
93 | /* add a pin to the list referred to by node_set */ |
||
94 | /********************************************************************/ |
||
11 | mjames | 95 | void add_equivalent_pin( socket_t * current_chip,equivalent_node_set_t * node_set , char * ident) { |
96 | equivalent_node_t * ptr; |
||
97 | equivalent_node_t * equiv_node; |
||
98 | node_t * node; |
||
99 | if (! current_chip) { |
||
100 | Log(LOG_ERROR,"-- Current chip not known for equivalent pin creation\n"); |
||
101 | return; |
||
102 | } |
||
2 | mjames | 103 | |
11 | mjames | 104 | node = find_node(current_chip,Ident,ident,Create); |
105 | /* no pin called 'ident ?? */ |
||
106 | if((level &1) && !node) { |
||
107 | Log(LOG_ERROR,"-- Error : Pin Equivalent : cannot find pin %s(%s)\n",current_chip->name,ident); |
||
108 | return; |
||
109 | } |
||
2 | mjames | 110 | |
11 | mjames | 111 | /* pin already equivalent to another ? */ |
112 | if((level &1) && node->equivalent_nodes) { |
||
113 | Log(LOG_ERROR,"-- Error : Pin Equivalent : pin %s(%s) already member of set\n",current_chip->name,ident); |
||
114 | return; |
||
115 | } |
||
116 | |||
117 | /* pin is acceptable so note it */ |
||
118 | equiv_node = calloc(1,sizeof ( equivalent_node_t )); |
||
119 | if (!node_set->nodes) { |
||
120 | /* new node */ |
||
121 | node_set->nodes = equiv_node; |
||
122 | } |
||
123 | else { |
||
124 | ptr = node_set->nodes; |
||
125 | while (ptr->next) |
||
126 | ptr=ptr->next; |
||
127 | ptr->next = equiv_node; |
||
128 | } |
||
129 | equiv_node->node = node; |
||
130 | } |
||
2 | mjames | 131 | |
132 | /********************************************************************/ |
||
11 | mjames | 133 | /* this function will verify the current list of nodes that are equivalent, and if there is more than |
134 | one in the list then it will add them to the equivalent node list of the |
||
2 | mjames | 135 | chip (if only one pin is equivalent to itself then it is a waste of time .... ) */ |
136 | /********************************************************************/ |
||
11 | mjames | 137 | void check_equivalent_pins(socket_t * current_chip, equivalent_node_set_t * node_set ) { |
2 | mjames | 138 | |
11 | mjames | 139 | equivalent_node_t * curr_node, * prev; |
140 | |||
141 | int equiv_count; |
||
2 | mjames | 142 | |
11 | mjames | 143 | if(!node_set) |
144 | return; |
||
2 | mjames | 145 | |
11 | mjames | 146 | /* count equivalent nodes */ |
147 | curr_node = node_set->nodes; |
||
148 | equiv_count = 0; |
||
149 | while(curr_node) { |
||
150 | equiv_count ++; |
||
151 | curr_node = curr_node->next; |
||
152 | }; |
||
2 | mjames | 153 | |
11 | mjames | 154 | /* delete info if not sufficent equivalent nodes */ |
155 | if(equiv_count < 2) { |
||
156 | curr_node = node_set->nodes; |
||
157 | while(curr_node) { |
||
158 | prev = curr_node; |
||
159 | curr_node = curr_node->next; |
||
160 | free(prev); |
||
161 | }; |
||
162 | free(node_set); |
||
163 | Log(LOG_ERROR,"-- Warning : insufficient equivalent pins in list\n"); |
||
164 | return; |
||
165 | } |
||
2 | mjames | 166 | |
11 | mjames | 167 | /* join the list to the socket as it is now validated */ |
168 | curr_node = node_set->nodes; |
||
169 | while(curr_node) { |
||
170 | /* flag each node as being a member of an equivalent set */ |
||
171 | curr_node->node->equivalent_nodes = node_set; |
||
172 | curr_node = curr_node->next; |
||
173 | } |
||
174 | |||
2 | mjames | 175 | |
11 | mjames | 176 | /* add an additional equivalent node set */ |
177 | node_set->next = current_chip->equivalent_node_set; |
||
178 | current_chip->equivalent_node_set = node_set; |
||
2 | mjames | 179 | |
11 | mjames | 180 | return ; |
181 | } |
||
2 | mjames | 182 | |
183 | /********************************************************************/ |
||
184 | |||
11 | mjames | 185 | void list_equivalent_pins(FILE * f, socket_t * dev) { |
186 | int itemcnt; |
||
187 | equivalent_node_t * curr_node; |
||
188 | equivalent_node_set_t * curr_set; |
||
189 | |||
190 | curr_set = dev->equivalent_node_set; |
||
191 | |||
192 | while (curr_set) { |
||
193 | if (curr_set->nodes) { |
||
194 | curr_node=curr_set->nodes; |
||
195 | fprintf(f," EQUIVALENT ( "); |
||
196 | itemcnt = 2; |
||
197 | while (curr_node) { |
||
198 | if (curr_node->next) { |
||
199 | fprintf(f,"%s; ",curr_node->node->identifier); |
||
200 | itemcnt++; |
||
201 | if (itemcnt > 6) { |
||
202 | fprintf(f,"\n "); |
||
203 | itemcnt = 0; |
||
204 | } |
||
205 | } |
||
206 | else |
||
207 | fprintf(f,"%s);\n",curr_node->node->identifier); |
||
208 | curr_node= curr_node->next; |
||
2 | mjames | 209 | } |
11 | mjames | 210 | } |
211 | curr_set = curr_set->next; |
||
212 | } |
||
213 | } |
||
214 | |||
2 | mjames | 215 | |
216 | /******************************************************************** |
||
217 | * copies the equivalent pins list from template to device instance * |
||
218 | * uses the functions above to ensure validation is consistently * |
||
11 | mjames | 219 | * performed |
2 | mjames | 220 | ********************************************************************/ |
11 | mjames | 221 | void copy_equivalent_pins(socket_t * template,socket_t * dev ) { |
222 | equivalent_node_t * curr_node ; |
||
223 | equivalent_node_set_t * curr_set ,* new_set; |
||
2 | mjames | 224 | |
11 | mjames | 225 | /* trap use of template when none is actually given */ |
226 | if (!template || !dev) |
||
227 | return; |
||
228 | if(level &1) |
||
229 | { |
||
230 | Log(LOG_GENERAL,"copying equivalent pins from template %s to socket %s\n", |
||
231 | template->type,dev->identifier); |
||
232 | } |
||
233 | curr_set = template->equivalent_node_set; |
||
2 | mjames | 234 | |
11 | mjames | 235 | while (curr_set) { |
236 | new_set = begin_equivalent_pins(); |
||
237 | /* create a set of equivalent pins to copy into */ |
||
238 | |||
239 | curr_node = curr_set->nodes; |
||
240 | |||
241 | while (curr_node) { |
||
242 | add_equivalent_pin( dev,new_set , curr_node->node->identifier); |
||
243 | /* traverse list */ |
||
244 | curr_node= curr_node->next; |
||
245 | } |
||
246 | |||
247 | check_equivalent_pins(dev, new_set ); |
||
248 | curr_set = curr_set->next; |
||
249 | } |
||
2 | mjames | 250 | |
11 | mjames | 251 | } |
2 | mjames | 252 | |
253 | |||
11 | mjames | 254 | /* function to jumper together all equivalent pins on a device : |
255 | at the moment it does not distinguish between EPLD and non -epld devices */ |
||
2 | mjames | 256 | /* the endpoint is a socket that may be used */ |
11 | mjames | 257 | void jumper_equivalent_pins(void) |
258 | { |
||
259 | char equiv_buff [MAXIDLEN]; |
||
260 | equivalent_node_t * curr_ref; |
||
261 | equivalent_node_set_t * node_set ; |
||
262 | |||
263 | socket_t * dev; |
||
264 | |||
265 | net_t * top_net, * current_net; |
||
2 | mjames | 266 | |
11 | mjames | 267 | dev = socket_head; |
268 | |||
269 | |||
270 | while(dev) { |
||
271 | /* any equivalent pins */ |
||
272 | if (dev->equivalent_node_set) { |
||
2 | mjames | 273 | #if defined DEBUG_EQUIV |
11 | mjames | 274 | Log(LOG_GENERAL,"-- Device %s has equivalent pins\n",dev->identifier); |
2 | mjames | 275 | #endif |
11 | mjames | 276 | node_set = dev->equivalent_node_set; |
277 | while(node_set) { |
||
278 | /* create a top level jumper name made out device ID concatenated with |
||
279 | current pin IDs */ |
||
280 | sprintf(equiv_buff,"E_%s",dev->identifier); |
||
281 | curr_ref = node_set->nodes; |
||
282 | while(curr_ref) { |
||
283 | current_net = curr_ref->node->net; |
||
284 | /* if there is a net attached to the pin it is a routed net. |
||
285 | only make the jumper if it is actually a usable net for routing. */ |
||
286 | if (current_net && IS_ROUTABLE(current_net->how_routed)) { |
||
287 | strcat(equiv_buff,"_"); |
||
288 | strcat(equiv_buff,curr_ref->node->identifier); |
||
289 | } |
||
290 | curr_ref=curr_ref->next; |
||
291 | } |
||
292 | |||
293 | |||
294 | /* printf("Making %s\n",equiv_buff); */ |
||
295 | top_net = find_net(&routed_list,Ident,equiv_buff,Create); |
||
296 | top_net->how_joined = Jumpered; |
||
2 | mjames | 297 | #if defined DEBUG_EQUIV |
11 | mjames | 298 | Log(LOG_GENERAL,"-- making jumper %s\n",equiv_buff); |
2 | mjames | 299 | #endif |
11 | mjames | 300 | curr_ref = node_set->nodes; |
301 | while(curr_ref) { |
||
302 | current_net = curr_ref->node->net; |
||
303 | /* if there is a net attached to the pin it is a routed net. |
||
304 | only make the jumper if it is actually a usable net for routing. */ |
||
305 | if (current_net && IS_ROUTABLE(current_net->how_routed)) { |
||
2 | mjames | 306 | #if defined DEBUG_EQUIV |
11 | mjames | 307 | Log(LOG_GENERAL,"-- connecting net %s ( pin %s(%s))\n", |
308 | curr_ref->node->net->identifier, |
||
309 | dev->identifier, |
||
310 | curr_ref->node->identifier); |
||
2 | mjames | 311 | #endif |
11 | mjames | 312 | current_net->external_node = NULL; /* jumpered by net name */ |
313 | transfer_net_to_subnet(&routed_list, |
||
314 | top_net, current_net); |
||
315 | |||
316 | } |
||
317 | |||
318 | |||
319 | curr_ref = curr_ref->next; |
||
320 | } |
||
321 | /* no child nets or jumper joins only one subnet : delete jumper */ |
||
322 | if(!top_net->subnets || !top_net->subnets->joined_nets) |
||
323 | disconnect_jumper( &routed_list,top_net); |
||
324 | |||
2 | mjames | 325 | |
11 | mjames | 326 | node_set = node_set->next; |
327 | } |
||
328 | } |
||
329 | |||
330 | dev = dev->next; |
||
2 | mjames | 331 | |
11 | mjames | 332 | } |
333 | } |
||
334 | |||
2 | mjames | 335 |