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 |