Subversion Repositories Vertical

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/*
11 mjames 2
 * $Header: c:\\cygwin\\cvsroot/Vert03/vertlib/routing.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $
2 mjames 3
 *
4
 * $Log: routing.c,v $
5
 * Revision 1.1.1.1  2003/11/04 23:34:57  mjames
6
 * Imported into local repositrory
7
 *
8
 * Revision 1.19  2003/01/02 21:37:17  mjames
9
 * Experiment on creating NOT_ROUTABLE_H and NOT_ROUTABLE_L
10
 * properties on the nets so that pin jumpers can be made without a problem.
11
 *
12
 * Still need to sort out pin assignments made to these not_routable nets
13
 * which will become legal in some cases so that pullups and pulldown
14
 * pins can be used on the FPGA.
15
 *
16
 * Revision 1.18  2002/12/09 10:31:49  mjames
17
 * Corrected 2 warnings about #ident
18
 * Added warning about "chip X1" which gets confused with component called "X1"
19
 *
20
 * Revision 1.17  2002/09/27 22:29:31  MJAMES
21
 * Added lhs_expr for cases like
22
 *
23
 * x(0) <= y
24
 *
25
 * where x is std_logic_vector(0 downto 0) and y is std_logic.
26
 *
27
 * Revision 1.16  2002/08/23 09:50:21  mjames
28
 * Altered pin_group search pattern from
29
 * chip_exp.pin_exp to chip_exp(pin_exp) as this is clearer.
30
 *
31
 * Revision 1.15  2001/10/31 22:20:16  mjames
32
 * Tidying up problematical comments caused by CVS
33
 * 'intelligent' comment guessing
34
 *
35
 * Revision 1.14  2001/10/31 16:18:04  mjames
36
 * Added a datastructure to hide regular expression information from programs.
37
 * Changed call to regexec to indicate 0 subexpressions to be matched
38
 * rather than a number dependent on strlen(string) which was wrong.
39
 *
40
 * Revision 1.13  2001/10/10 20:18:21  mjames
41
 * Added a vert_regcomp function to compile regular expressions
42
 * with '^' (match start string) and  '$' (match end string) bracketing
43
 * this => wildcard must match entire string not just a part of it.
44
 *
45
 * Revision 1.12  2001/10/07 20:50:51  mjames
46
 * Added wildcard checking (warn user about
47
 * using wildcard '*' on the end of a string in stead of wildcard '.*')
48
 *
49
 * Revision 1.11  2001/09/28 10:16:20  mjames
50
 * Modified to use auto variable pointing at regular expression instead of
51
 * allocating one via calloc.
52
 *
53
 * Revision 1.10  2001/09/25 23:15:23  mjames
54
 * Converted wildcards to use proper regexp pattern match library
55
 *
56
 * Revision 1.9  2001/08/23 20:06:44  mjames
57
 * Added 'reserve' command for use with preroute commands.
58
 * This command provides the 'correct' documented pin reservation
59
 * behaviour.
60
 *
61
 * Revision 1.8  2001/08/09 20:04:03  mjames
62
 * Tidying up indentation
63
 *
64
 * Revision 1.7  2001/07/20 14:49:42  mjames
65
 * Corrected reading names in on multiple boards : if present in a database file
66
 * when reading in a suffixed design
67
 * e.g. CHIP fred
68
 * Will also get its name suffixed.
69
 *
70
 * Revision 1.6  2001/07/20 10:47:43  mjames
71
 * Allowed setting of pin routing group properties on pins on nets
72
 * by the
73
 * "set pin" command
74
 *
75
 * Revision 1.5  2001/07/09 15:39:38  mjames
76
 * Reduced verbose diagnostics
77
 *
78
 * Revision 1.4  2001/06/07 14:00:04  MJAMES
79
 * Producing an error on failing to fix pins
80
 *
81
 * Revision 1.3  2001/06/06 12:10:17  mjames
82
 * Move from HPUX
83
 *
84
 * Revision 1.2  2001/01/02 07:53:53  mjames
85
 * Made changes to allow for interface with TCL/Tk
86
 *
87
 * Revision 1.1.1.1  2000/10/19 21:58:39  mjames
88
 * Mike put it here
89
 *
90
 * Revision 1.57  2000/10/04  10:37:09  10:37:09  mjames (Mike James)
91
 * Modified for Vertical2 : support COMPONENTS and SIGNALS
11 mjames 92
 *
2 mjames 93
 * Revision 1.57  2000/10/04  10:37:09  10:37:09  mjames (Mike James)
94
 * Part of Release PSAVAT01
11 mjames 95
 *
2 mjames 96
 * Revision 1.56  2000/10/02  11:04:20  11:04:20  mjames (Mike James)
97
 * new_vhdl
11 mjames 98
 *
2 mjames 99
 * Revision 1.55  2000/09/27  14:42:20  14:42:20  mjames (Mike James)
100
 * Part of Release Sep_27_ST_2000
11 mjames 101
 *
2 mjames 102
 * Revision 1.54  2000/09/21  10:15:50  10:15:50  mjames (Mike James)
103
 * Part of Release Sep21Alpha
11 mjames 104
 *
2 mjames 105
 * Revision 1.53  2000/08/25  09:57:16  09:57:16  mjames (Mike James)
106
 * Part of Release Aug25_alpha
11 mjames 107
 *
2 mjames 108
 * Revision 1.52  2000/08/16  08:57:32  08:57:32  mjames (Mike James)
109
 * Part of Release CD01_Aug2000
11 mjames 110
 *
2 mjames 111
 * Revision 1.51  2000/08/16  08:55:43  08:55:43  mjames (Mike James)
112
 * corrected routing/unroutable nets errors
11 mjames 113
 *
2 mjames 114
 * Revision 1.50  2000/08/14  14:45:13  14:45:13  mjames (Mike James)
115
 * Part of Release Aug_14_2000
11 mjames 116
 *
2 mjames 117
 * Revision 1.49  2000/08/14  14:43:31  14:43:31  mjames (Mike James)
118
 * Added power pins
11 mjames 119
 *
2 mjames 120
 * Revision 1.48  2000/08/11  08:30:33  08:30:33  mjames (Mike James)
121
 * Part of Release Aug_11_2000
11 mjames 122
 *
2 mjames 123
 * Revision 1.47  2000/08/09  10:31:49  10:31:49  mjames (Mike James)
124
 * Part of Release Aug_9_2000
11 mjames 125
 *
2 mjames 126
 * Revision 1.46  2000/05/31  11:43:00  11:43:00  mjames (Mike James)
127
 * Part of Release May_31_2000
11 mjames 128
 *
2 mjames 129
 * Revision 1.45  2000/05/08  17:01:39  17:01:39  mjames (Mike James)
130
 * Part of Release May_8_2000
11 mjames 131
 *
2 mjames 132
 * Revision 1.44  2000/05/08  16:59:32  16:59:32  mjames (Mike James)
133
 * Part of Release May_8_2000
11 mjames 134
 *
2 mjames 135
 * Revision 1.43  2000/05/08  16:57:09  16:57:09  mjames (Mike James)
136
 * Part of Release May_8_2000
11 mjames 137
 *
2 mjames 138
 * Revision 1.42  2000/03/08  16:19:29  16:19:29  mjames (Mike James)
139
 * New version including PC
11 mjames 140
 *
2 mjames 141
 * Revision 1.39  2000/01/20  15:58:50  15:58:50  mjames (Mike James)
142
 * Part of Release R22
11 mjames 143
 *
2 mjames 144
 * Revision 1.38  99/12/22  11:15:30  11:15:30  mjames (Mike James)
145
 * Part of Release Dec_22_1999
11 mjames 146
 *
2 mjames 147
 * Revision 1.37  99/06/25  14:35:50  14:35:50  mjames (Mike James)
11 mjames 148
 * Added in reference to expression.h, but no changes made
2 mjames 149
 * to the function of acfread yet.
11 mjames 150
 *
2 mjames 151
 * Revision 1.36  99/06/18  09:26:23  09:26:23  mjames (Mike James)
11 mjames 152
 *
2 mjames 153
 * Revision 1.35  99/05/04  09:52:46  09:52:46  mjames (Mike James)
154
 * General checkin
11 mjames 155
 *
2 mjames 156
 * Revision 1.33  98/11/27  15:16:05  15:16:05  mjames (Mike James)
157
 * FIxed small errors
11 mjames 158
 *
2 mjames 159
 * Revision 1.32  98/06/15  14:19:24  14:19:24  mjames (Mike James)
160
 * Removed and added Route Create from general routing algorithm.
161
 * Added routing routing groups
11 mjames 162
 *
2 mjames 163
 * Revision 1.31  98/04/24  14:09:05  14:09:05  mjames (Mike James)
164
 * Removed 'create routes' from default routing algorithm set
165
 * used when route command is used.
11 mjames 166
 *
2 mjames 167
 * Revision 1.30  98/03/16  11:39:50  11:39:50  mjames (Mike James)
168
 * Removed an old bug - suffixing of PCB names has been broken for about
169
 * a year. If a pcb were read in non-suffixed and then another with a suffix,
170
 * the suffix would be applied over all of the sockets and nets, not just the new ones.
11 mjames 171
 *
2 mjames 172
 * Revision 1.29  98/02/11  11:27:14  11:27:14  mjames (Mike James)
173
 * Checked in for version 6.2a
11 mjames 174
 *
2 mjames 175
 * Revision 1.28  97/04/23  08:43:23  08:43414:23  mjames (Mike James)
176
 * CHecked in for release rel23041997
11 mjames 177
 *
2 mjames 178
 * Revision 1.27  97/01/03  13:35:24  13:35:24  mjames (Mike James)
11 mjames 179
 * Tidied up the ensure_reserved() function. Added in a flag to
2 mjames 180
 * indicate that a net has been processed by ensure_reserved()
181
 * And so is not in error for only having 0 or 1 nodes names (which is the
182
 * case for a 1 or 2 node net that has been processed. One of the nodes will
183
 * remain unnnamed and this will result in 0 or 1 nodes apparently in use
11 mjames 184
 *
2 mjames 185
 * Revision 1.26  96/12/23  15:14:38  15:14:38  mjames (Mike James)
11 mjames 186
 * This code for fixing pins has been split from the 'exact path'
2 mjames 187
 * routing as the algorithm has become more reliable
188
 * if there are two independednt routines.
11 mjames 189
 *
2 mjames 190
 * Revision 1.25  96/12/13  08:43:11  08:43:11  mjames (Mike James)
191
 * Update to v5.1, added Write ID , exact routing
11 mjames 192
 *
2 mjames 193
 * Revision 1.24  96/08/06  13:38:54  13:38:54  mjames (Mike James)
194
 * Added FIX_LOCATION pin attribute to netlist
195
 *
196
 * Revision 1.23  96/07/19  14:38:44  14:38:44  mjames (Mike James)
197
 * Update to give to PRL
198
 *
199
 * Revision 1.22  1996/07/12  15:52:12  mjames
200
 * Sorted out things like Alias and Jumpers
201
 * Work Correctly
202
 * Print COrrectly
203
 *
204
 * Revision 1.21  96/07/09  15:54:04  15:54:04  mjames (Mike James)
205
 * Altered aliasing to make it hierarchical, also for jumpering
206
 *
207
 * Revision 1.20  96/06/17  13:01:45  13:01:45  mjames (Mike James)
208
 * Altered the printing of JUMPERED and ALIASED nets
209
 * ,
210
 *
211
 * Revision 1.19  96/06/11  14:46:00  14:46:00  mjames (Mike James)
212
 * Tidying up done to remove an error created by
213
 * trying to fix the wrong symprom of a bug
214
 *
215
 * Revision 1.18  96/06/11  14:11:47  14:11:47  mjames (Mike James)
216
 * Added hierarchical jumpering
217
 *
218
 * Revision 1.17  96/06/04  11:53:22  11:53:22  mjames (Mike James)
219
 * Added the ability to jumper nets by reference to a node on the nets
220
 *
221
 * Revision 1.16  96/05/29  10:53:34  10:53:34  mjames (Mike James)
222
 * Added renaming of IDs for nets and sockets.
223
 *
224
 * Revision 1.15  96/04/26  16:02:28  16:02:28  mjames (Mike James)
225
 * Altered inside/outside determination of signal directions
226
 *
227
 * Revision 1.14  96/04/15  14:19:36  14:19:36  mjames (Mike James)
228
 * Checkin before datatype printing
229
 * modifications
230
 *
231
 * Revision 1.13  96/03/29  14:46:32  14:46:32  mjames (Mike James)
232
 * Added VHDL netlist writing to the capabilities of ACFREAD
233
 *
234
 * Revision 1.12  96/03/26  07:21:16  07:21:16  mjames (Mike James)
235
 * Added LIST XREF socket-name command
236
 *
237
 * Revision 1.11  96/03/19  08:53:43  08:53:43  mjames (Mike James)
238
 * Minor tweaks
239
 *
240
 * Revision 1.7  96/03/13  15:37:34  15:37:34  mjames (Mike James)
241
 * Altered the name_pref field to be used to indicate the routing algorithm used
242
 * to route this net.
243
 *
244
 * Revision 1.6  96/02/13  09:13:30  09:13:30  mjames (Mike James)
245
 * Updated to be version 2.0 with net joining
246
 *
247
 * Revision 1.5  96/02/08  15:28:31  15:28:31  mjames (Mike James)
248
 * First release
249
 *
250
 * Revision 1.4  96/02/07  16:01:35  16:01:35  mjames (Mike James)
251
 * Added correct RCS header
252
 *
253
 * Revision 1.3  96/02/07  15:50:45  15:50:45  mjames (Mike James)
254
 * Added RCS ident message
255
 *
256
 * Revision 1.2  96/02/07  11:04:25  11:04:25  mjames (Mike James)
257
 * Checkin before adding new command parsing to program
258
 *
259
 * Revision 1.1  96/01/10  13:14:36  13:14:36  mjames (Mike James)
260
 * Initial revision
261
 *  */
262
 
11 mjames 263
#include <stdio.h>
264
#include <string.h>
265
#include <stdlib.h>
266
#include <ctype.h>
267
#include <sys/types.h>
268
#include <regex.h>
2 mjames 269
 
11 mjames 270
#include "vertcl_main.h"
2 mjames 271
#include "expression.h"
272
#include "generic.h"
11 mjames 273
#include "database.h"
2 mjames 274
#include "lx_support.h"
11 mjames 275
#include "routing.h"
276
#include "unrouted.h"
277
#include "chck_names.h"
278
#include "statistics.h"
279
#include "cmdparse.h"
280
#include "cmdlog.h"
2 mjames 281
#include "sorting.h"
282
 
11 mjames 283
#ident "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/routing.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $"
2 mjames 284
 
285
 
11 mjames 286
 
2 mjames 287
/* used in search for pre-existing path */
288
int MaxNodesForSearch = MAX_NODES_FOR_PATH_SEARCH;
289
 
290
 
11 mjames 291
int global_group_flag = 0 ;
292
 
293
static void
294
get_num_nets (net_t * list, char *message)
2 mjames 295
{
11 mjames 296
  int i = 0;
297
  while (list)
298
    {
299
      list = list->next;
300
      i++;
301
    }
302
  Log (LOG_GENERAL, "-- %-4d %s\n", i, message);
2 mjames 303
}
304
 
11 mjames 305
void
306
count_nets (char *message)
2 mjames 307
{
308
 
11 mjames 309
  Log (LOG_GENERAL, "-- Routing Statistics : %s\n", message);
310
 
311
  get_num_nets (unrouted_list, "Connections not routed");
312
  get_num_nets (routed_list, "Nets connected but not in use");
313
  get_num_nets (named_list, "Nets connected and used by named signals");
314
  Log (LOG_GENERAL, "-- \n");
315
 
2 mjames 316
}
317
 
11 mjames 318
 
2 mjames 319
/* clear the routing flags on the node references on a particular net */
320
/* this tries to avoid the situation where two unrouted nets both find the
321
   same pin connection on the routed net when it is searched to see if
322
   it is connected to a socket. The old algorithm found the first
323
   connected pin on a socket and then used this  */
11 mjames 324
void clear_routing_flags(noderef_t * net_nodes)
2 mjames 325
{
11 mjames 326
  while (net_nodes)
327
    {
328
      /* Indicate not already visited all nodes on this net */
329
      net_nodes->r_flag = 0;
330
      net_nodes = net_nodes->next;
331
    }
332
 
2 mjames 333
}
334
 
11 mjames 335
 
336
 
2 mjames 337
/* does a net reach the wanted socket with the pin direction correct
338
   and if we are using pin_groups is this pin in the correct group */
11 mjames 339
noderef_t * search_net_for_socket (noderef_t * wanted_ref,
340
                                   noderef_t * net_nodes,
341
                                   int use_group_mask)
342
{
343
  int route_flags=0;
344
  node_t *wanted = wanted_ref->node;
345
  if (use_group_mask)
346
    route_flags     = wanted->socket->route_flags;
347
  while (net_nodes)
348
    {
349
      node_t *nnode = net_nodes->node;
2 mjames 350
 
11 mjames 351
      /* if we have not already visited this node */
352
      if ((net_nodes->r_flag == 0) &&
353
              (nnode->socket == wanted->socket) &&
354
      /* either
355
         NOT a fixed pin (pin direction NOT pin location ) or
356
         IS a fixed pin and in the right direction : probably can use compat_pins info
357
         from template.c here MDJ Aug 2000 */
358
             (nnode->fixed_pin == 0 || nnode->pindir == wanted_ref->pindir) &&
359
      /* either
360
         Not using pin groups
361
         or the pin group is the same */
362
         (!route_flags || ((nnode->pin_group & route_flags)  == (wanted->pin_group & route_flags )))
363
          )
364
        {
365
          net_nodes->r_flag = 1;
366
          return (net_nodes);
367
        }
368
      net_nodes = net_nodes->next;
369
    }
370
  return NULL;
2 mjames 371
}
372
 
11 mjames 373
 
2 mjames 374
/* removes a net from the list of nets */
375
 
11 mjames 376
net_t *remove_net (net_t ** list, net_t * net)
2 mjames 377
{
11 mjames 378
  noderef_t *refs, *temp;
379
  net_t *next_net, * prev_net;
380
/*
381
   printf("-- removing %s (%s) (%p) list %p\n",
382
   net->identifier,net->name,*list,net);
383
 */
384
  next_net = net->next;
385
  prev_net = net->prev;
386
  /* fill in the gap */
387
/* removal from head of list is different */
388
  if (net == *list) {
389
    *list = next_net;
390
    if (next_net)
391
      next_net->prev = NULL;
392
    }
393
  else {
394
 
395
    if (prev_net)
396
      prev_net->next = net->next;
397
    if (next_net)
398
      next_net->prev = net->prev;
399
    };
2 mjames 400
 
401
 
11 mjames 402
  /* get pointer to the nodes on this net */
403
  refs = net->nodes;
2 mjames 404
 
11 mjames 405
  /* do not destroy the net linking structure
406
     as it could still be pointed at by unused unrouted
407
     nodes that are still attached to sockets which you will
408
     find if you examine all of the nodes attached to a socket. */
409
  net->list_ref = NULL;         /* this net is not held on any list now */
410
  net->nodecount = 0;
411
  net->nodes = NULL;
412
/*net->subnets  = NULL; do not destroy subnets , used for alias listing */
413
/*change name to something worrying */
414
  net->name = "[DELETED so this is INVISIBLE]";
2 mjames 415
 
11 mjames 416
  /* remove the nodes on this net */
417
  while (refs)
418
    {
419
      refs->node->refcount--;   /* one less reference */
420
      temp = refs->next;
421
      free (refs);
422
      refs = temp;
423
    };
424
 
425
 
426
 
427
  return next_net;
2 mjames 428
}
429
 
11 mjames 430
 
2 mjames 431
/* moves a net from one list to another */
11 mjames 432
void
433
transfer_net_to_named (net_t ** from_list,
434
                       net_t * net)
2 mjames 435
{
436
 
11 mjames 437
/* remove the node from the 'from' list */
438
/*
439
   printf("-- transferring %s (%s) (%p) list %p\n",net->identifier,net->name,*from_list,net);
440
 */
441
  if (net->next)
442
    net->next->prev = net->prev;
443
  if (net->prev)
444
    net->prev->next = net->next;
2 mjames 445
 
446
 
11 mjames 447
  if (net == *from_list)
448
    *from_list = net->next;
2 mjames 449
 
11 mjames 450
  net->list_ref = &named_list;  /* net now is on the named list */
2 mjames 451
 
11 mjames 452
 
453
  /* stick net on tail of 'to' list */
454
  if (named_tail)
455
    named_tail->next = net;
456
  net->prev = named_tail;
457
 
458
  if (!named_list)
459
    named_list = net;
460
  net->next = NULL;
461
 
462
  named_tail = net;
463
 
464
 
2 mjames 465
}
466
 
11 mjames 467
 
2 mjames 468
/* ******************************************** */
469
/*
470
   This function tidies up, setting net names for all of the pins on the
471
   net that have not been used by the unrouted net, to a net whose name
472
   is RSV00001Z  where the 00001 is a sequence number .
473
   it also names the routed net
474
 
475
   Recently modified such that external connections do not get this treatment
476
   These pins take on the names of the nets connected regardless, as they are
477
   not EPLDs, so there won't be a complaint by Maxplus2.
478
 */
479
 
11 mjames 480
/* the dummy node count is external to the naming routine, as it
2 mjames 481
   is used in the ensure_reservation code */
11 mjames 482
  static int nodecount = 0;
2 mjames 483
 
11 mjames 484
void
485
name_unused_nodes (net_t * routed_net,
486
                   char *identifier)
2 mjames 487
{
11 mjames 488
  noderef_t *routed_nodes;
489
  char *unused_ident;
2 mjames 490
 
491
 
11 mjames 492
  routed_nodes = routed_net->nodes;
493
  while (routed_nodes)
494
    {
495
      node_t *cnode = routed_nodes->node;
496
      if (routed_nodes->node->net_assigned == 0)
497
           {                    /* this node hasnt yet been used by a net */
498
           if (cnode->socket->is_external == 0)
499
            {                   /* EPLD or internal node */
500
              /* every reserved pin is unique, so make it a new name c */
501
              unused_ident = calloc (RES_NAMLEN + 1, sizeof (char));
502
              sprintf (unused_ident, RES_FMT, nodecount++);
503
              cnode->name = unused_ident;       /* use the created name */
2 mjames 504
 
11 mjames 505
              cnode->net = routed_net;  /* tell the node its got a net assigned */
506
              cnode->pindir = INPUT;
507
/*            cnode->datatype = "Named through naming unused nodes";*/ 
508
/*        cnode->datatype = routed_net->datatype; */
509
              cnode->vhdltype = default_vhdl_datatype;  /* put something there */
510
          cnode->lhs_expr = NULL;
2 mjames 511
 
11 mjames 512
              cnode->orig_vhdltype = NULL;      /* put something there */
2 mjames 513
 
11 mjames 514
            }
515
          else
516
            {                   /* An external flag See SET EXTERNAL <prefix> */
517
              cnode->name = identifier;         /* same name as the net */
518
 
519
              cnode->net = routed_net;  /* tell the node its got a net assigned */
520
              cnode->pindir = INPUT;
521
/*            cnode->datatype = routed_net->datatype;   *//* routed_net->datatype; */
522
              cnode->vhdltype = routed_net->vhdltype;   /* put something there */
523
          cnode->lhs_expr = NULL;
524
              cnode->orig_vhdltype = NULL;      /* put something there */
525
            }
526
 
527
          cnode->net_assigned = 1;      /* tell the node its got a net assigned */
528
          cnode->in_use = 0;    /* if the node is in use then set its flag */
529
 
530
        }
531
      routed_nodes = routed_nodes->next;
532
    }
2 mjames 533
}
534
 
535
/* ******************************************** */
536
/* connect up the routed and  unrouted nets */
537
 
11 mjames 538
void
539
combine_sub (net_t * routed_net,
540
             net_t * unrouted_net)
2 mjames 541
{
11 mjames 542
  noderef_t *routed_nodes, *unrouted_nodes;
2 mjames 543
 
11 mjames 544
/*
545
   printf("-- Moving net %s onto routing of %s\n",
546
   unrouted_net->identifier,routed_net->identifier);
547
 */
2 mjames 548
 
11 mjames 549
  unrouted_nodes = unrouted_net->nodes;
550
  routed_nodes = routed_net->nodes;
551
  if (level & 2) {
552
    Log(LOG_GENERAL,"#COMBINE_SUB routed=%s, unrouted=%s\n",
553
      unrouted_net->name,routed_net->name);
554
    Log(LOG_GENERAL," type def routed = %d unrouted=%d\n",
555
      unrouted_net->type_defined,routed_net->type_defined);
556
    }
557
  /* for each node on the routed net, is this net needed on
558
     the unrouted net */
559
  while (unrouted_nodes)
560
    {
561
      noderef_t *route_ref;
562
      node_t *routed_node, *unrouted_node;
563
      unrouted_node = unrouted_nodes->node;
2 mjames 564
 
11 mjames 565
      /* we have a route, this search _will succeed .. if it doesnt .. oops. */
566
      /* do not need to worry about the groups here as the nets have already
567
         been found */
2 mjames 568
 
11 mjames 569
/* Changed MDJ July 2001 : made it a prerequisite to check if the pin_group matches */
2 mjames 570
 
11 mjames 571
      route_ref = search_net_for_socket (unrouted_nodes, routed_nodes,unrouted_node->pin_group);
2 mjames 572
 
573
 
574
 
575
 
11 mjames 576
      /* if we have found a node on the right socket on the
577
         routed net that has not yet been used  */
578
 
579
      if (route_ref)
580
        {
581
 
582
 
583
          routed_node = route_ref->node;
584
      if (level &2)
585
      Log(LOG_GENERAL,"info %s(%s)   '%s'\n",routed_node->socket->name,routed_node->identifier,
586
        route_ref->orig_name?route_ref->orig_name:unrouted_net->name);
587
 
588
          /*
589
             route_ref->r_flag = 1;
590
           *//* we are using this node */
591
          routed_node->pindir = unrouted_nodes->pindir;         /* the node reference holds the
592
                                                                   pin direction */
593
 
594
/*        routed_node->name = unrouted_net->identifier; Previous !!!*/
595
          if(route_ref->orig_name) {
596
            routed_node->name          = route_ref->orig_name;
597
            routed_node->vhdltype      = route_ref->vhdltype;
598
            routed_node->orig_vhdltype = route_ref->orig_vhdltype;
599
        routed_node->lhs_expr      = route_ref->lhs_expr;
600
        if (level & 2)
601
            Log(LOG_GENERAL,"# Info : found  rename to %s on %s\n", route_ref->orig_name, unrouted_net->identifier);
602
 
603
            }
604
          else {
605
            routed_node->name     = unrouted_net->identifier;
606
            routed_node->vhdltype = unrouted_nodes->vhdltype;
607
        routed_node->lhs_expr = unrouted_nodes->lhs_expr;
608
            routed_node->orig_vhdltype = unrouted_nodes->orig_vhdltype;
609
            }
610
/*        routed_node->datatype = unrouted_nodes->datatype; */
611
          routed_node->net = routed_net;        /* tell the node its got a net assigned */
612
          routed_node->in_use = 1;      /* if the node is in use then set its flag */
613
          routed_node->net_assigned = 1;
614
          routed_node->routed_net = NULL; /* all nodes on the routed net are
615
                                             about to belong to the named list */
616
 
617
 
618
 
619
        }
620
      if (level & 2)
621
      Log(LOG_GENERAL,"#\n");
622
      unrouted_nodes = unrouted_nodes->next;
623
    };
624
 
2 mjames 625
}
626
 
11 mjames 627
 
628
 
629
static void
630
combine_alias (net_t * routed_net,
631
               net_t * unrouted_net)
2 mjames 632
{
11 mjames 633
/*    printf("combining alias %s with routed %s\n",unrouted_net->identifier,
634
   routed_net->identifier);    */
635
  while (unrouted_net)
636
    {
637
    if (unrouted_net->how_joined == Aliased)
638
          {                     /* recursion for alias */
639
          if (unrouted_net->subnets)
640
            combine_alias (routed_net, unrouted_net->subnets);
641
          }
642
    else
643
          {
644
          /* and for each aliased subnet ... */
645
          clear_routing_flags (unrouted_net->nodes);
646
          /* printf("moving aliased net .%s.\n",unrouted_net->identifier); */
647
          combine_sub (routed_net,
648
                       unrouted_net);
649
        /*  name_unused_nodes (routed_net, unrouted_net->identifier); */
650
          }
651
    unrouted_net = unrouted_net->joined_nets;
652
    }
653
 
2 mjames 654
}
655
/* ******************************************** */
656
/* if a net was created by aliasing names, now we have to copy out each of
657
   the unrouted sub nets to the routed net - getting node names right
658
   in particular . Otherwise just do the one */
659
 
11 mjames 660
void
661
combine_routed_and_unrouted (net_t * routed_net,
662
                             net_t * unrouted_net)
2 mjames 663
{
11 mjames 664
  clear_routing_flags (routed_net->nodes);
665
  /* refer across to unrouted net for printout */
666
/*
667
   printf("Combining '%s' and '%s' \n",routed_net->identifier,
668
   unrouted_net->identifier);
669
 */
670
  routed_net->unrouted_reference = unrouted_net;
671
  routed_net->name = unrouted_net->identifier;
672
/* assumption here is that the datatype and vhdltype are the same */
673
/*  routed_net->datatype = unrouted_net->datatype; */
2 mjames 674
 
11 mjames 675
  routed_net->vhdltype = unrouted_net->vhdltype;
2 mjames 676
 
677
 
11 mjames 678
 
679
  if (unrouted_net->how_joined == Aliased)
680
    {
681
      /* preserve aliasing information */
682
      combine_alias (routed_net, unrouted_net);
683
    }
684
  else
685
    {
686
      clear_routing_flags (unrouted_net->nodes);
687
      combine_sub (routed_net,
688
                   unrouted_net);
689
 
690
    /*  name_unused_nodes (routed_net, unrouted_net->identifier); */
691
     }
2 mjames 692
}
693
 
11 mjames 694
 
2 mjames 695
/* **************************************************************** */
696
/* This function ensures net reservation is made for all internal
697
   nodes that are on internal sockets .
698
   If any external socket is on the net then all internal pins are reserved.
699
   Otherwise a single internal pin is left as a non-reserved driver */
11 mjames 700
 
701
void
702
ensure_reservation (void)
2 mjames 703
{
11 mjames 704
  char *unused_ident;
705
  net_t * net_head = routed_list;
706
  int skip; /* the number of nodes on the net to leave unreserved */
2 mjames 707
 
11 mjames 708
/*
709
   puts("ensure_reservation entered");
710
*/  while(net_head) {
711
    net_t * altered_net= NULL;
712
    if(net_head->nodecount>1 &&
713
       IS_ROUTABLE(net_head->how_routed)) {  /* ignore single node nets as they need to be external */
714
      noderef_t * routed_nodes = net_head->nodes;
715
      net_head->nodes_reserved = 0; /* Begin by clearing the flag */
716
      /* nets with external sockets cannot be allowed */
717
      if(net_head->has_external)
718
        skip=0;
719
      else
720
        skip=1;
721
/*        
722
      printf("Net '%s'\n",net_head->identifier);  
723
*/
724
      while (routed_nodes) {
725
        node_t *cnode = routed_nodes->node;
726
        if (cnode->net_assigned == 0 &&         /* this node hasnt yet been used by a net */
727
/* set the flag to stop count_nets_with_few_nodes() in statistics.c from complaining */         cnode->socket->is_external == 0) {      /* EPLD or internal node */
728
          net_head->nodes_reserved = 1;
729
              /* every reserved pin is unique, so make it a new name */
730
              if(skip==0) { /* skipped enough ? */
731
                unused_ident = calloc (RES_NAMLEN + 1, sizeof (char));
732
                sprintf (unused_ident, RES_FMT, nodecount++); /* shared node counter */
733
                cnode->name = unused_ident;     /* use the created name */
2 mjames 734
 
11 mjames 735
                cnode->net = net_head;  /* tell the node its got a net assigned */
736
                cnode->pindir = INPUT;
737
/*              cnode->datatype = "Named through naming unused nodes";*/        /* routed_net->datatype; */
738
                cnode->vhdltype = default_vhdl_datatype;        /* put something there */
739
            cnode->net_assigned = 1;
740
            cnode->lhs_expr = NULL;
741
            altered_net = net_head;
742
                }
743
              else
744
                skip--;
745
              }
746
 
747
        routed_nodes = routed_nodes->next;
748
        }
749
      } /* nodecount */
750
    net_head = net_head->next;
751
        if(altered_net)
752
          {
2 mjames 753
/*
754
          transfer_net_to_named (&routed_list, altered_net);
755
*/    }
11 mjames 756
    }
2 mjames 757
}
758
 
759
/* this function checks to see if the net identifier of an unrouted net matches that
760
   of a routed net, which is itself not routable */
761
void validate_unrouted (void)
762
{
11 mjames 763
  net_t *routed_net, *unrouted_net;
2 mjames 764
 
11 mjames 765
  unrouted_net = unrouted_list;
766
  while (unrouted_net)   {
767
    if (unrouted_net->identifier[0]) {
768
    /* search first for matching Identifier */
769
        routed_net = find_net (&routed_list, Ident, unrouted_net->identifier, Search);
2 mjames 770
 
11 mjames 771
/* located a net that could be a candidate . Validate routing status and
772
   report an error if there is a problem */
773
 
774
        if (routed_net && IS_NOT_ROUTABLE(routed_net->how_routed)) {
775
        noderef_t * nodes = unrouted_net -> nodes;
776
        unrouted_net -> how_routed = routed_net->how_routed;
777
        Log(LOG_ERROR,"-- WARNING : Routing : Net '%s' with following unrouted\n"
778
                      "--   nodes cannot be connected to an UNROUTABLE routed net\n",
779
                      unrouted_net->identifier);
780
        while(nodes) {
781
          Log(LOG_ERROR,"--   %s(%s)\n",nodes->node->socket->identifier,
782
                                        nodes->node->identifier);
783
          nodes = nodes->next;
784
          }
785
 
2 mjames 786
        }
11 mjames 787
      else
788
        unrouted_net -> how_routed = Free; /* can keep on routing this net */
789
      }
790
    unrouted_net = unrouted_net->next;
791
    }
792
  }
793
 
2 mjames 794
 
11 mjames 795
 
796
 
797
 
798
 
799
 
800
 
801
 
2 mjames 802
/* ******************************************** */
803
/* this procedure searches the unrouted nets one by one.
804
   if an unrouted net has the same name as a
805
   routed net, then all nodes on the unrouted net take on the
806
   routed net name , and the routed net's status is changed to reflect this
807
   name. All 'spare' nodes on the routed net are set to point at a 'reserved' net
808
   for future safety */
11 mjames 809
void
810
perform_routing_by_name (void)
2 mjames 811
{
11 mjames 812
  net_t *routed_net;
813
  noderef_t *routed_nodes, *unrouted_nodes;
814
  net_t *unrouted_net, *prev_net;
815
  int routed_ok;
2 mjames 816
 
11 mjames 817
  prev_net = NULL;
818
  unrouted_net = unrouted_list;
819
  while (unrouted_net)
820
    {
821
      routed_ok = 0;
822
      if (unrouted_net->identifier[0]  && IS_ROUTABLE(unrouted_net->how_routed))
823
        {
824
/* search first for matching Name then for matching Identifier */
2 mjames 825
 
11 mjames 826
          routed_net = find_net (&routed_list, Name, unrouted_net->identifier, Search);
827
          if (!routed_net)
828
            routed_net = find_net (&routed_list, Ident, unrouted_net->identifier, Search);
2 mjames 829
 
830
 
11 mjames 831
          if (routed_net && IS_ROUTABLE(routed_net->how_routed))
832
            {
833
              /* found a routed net,                    with this name or ident */
834
              /* check status of this net, see if it connects the right places */
835
              int f = 1;
836
/*
837
   printf("Found matching routed net \n");
838
 */
839
              unrouted_nodes = unrouted_net->nodes;
840
              routed_nodes = routed_net->nodes;
841
              clear_routing_flags (routed_nodes);
2 mjames 842
 
11 mjames 843
              while (unrouted_nodes && f)
844
                {
845
                  f = search_net_for_socket (unrouted_nodes,
846
                                             routed_nodes,1) != NULL;
847
                  unrouted_nodes = unrouted_nodes->next;
848
                }
849
 
850
              /* if f is 1 then the routed net connects all of the nodes on the
851
                 unrouted net */
852
              if (f)
853
                {
854
/*
855
   printf("and can join together sockets \n");
856
 */
857
                  /* Can fit nets together */
858
                  combine_routed_and_unrouted (routed_net, unrouted_net);
859
                  /* prevent this net from being recycled, move to
860
                     the fully named and routed list */
861
                  transfer_net_to_named (&routed_list, routed_net);
862
                  routed_net->how_routed = By_Name;     /* This net was routed by name !! */
863
                  routed_ok = 1;
864
                }
865
            }
866
        }
867
      if (routed_ok)
868
        /* remove the unrouted net from the list */
869
          unrouted_net = remove_net (&unrouted_list, unrouted_net);
870
    else
871
        /* Not removing net as algorithm hasnt found a match */
872
          unrouted_net = unrouted_net->next;
873
    };
874
  count_nets ("After routing by matching existing net names");
2 mjames 875
}
876
 
11 mjames 877
 
878
 
2 mjames 879
/************************************************************************/
11 mjames 880
/* this algorithm works by considering each of the routed nets in turn
2 mjames 881
   to see if there is an unrouted net 'fixed' to it. */
882
/************************************************************************/
11 mjames 883
 
884
void
885
perform_routing_by_fixed_net(void)
2 mjames 886
{
11 mjames 887
  net_t *unrouted_net,*routed_next;
888
  net_t *routed_net = routed_list;
889
  int routed_ok,f;
890
  while (routed_net) {
891
    routed_next = routed_net->next; /* 'next' will  be changed when a routed
892
                                       net is moved onto  the named list */
893
        routed_ok = 0;
894
    f = 1;
895
/*
896
    printf("Considering ROUTED '%s'\n",routed_net->identifier);
897
*/
898
    if(IS_ROUTABLE(routed_net->how_routed) &&
899
       routed_net->has_fix_location &&
900
       routed_net->unrouted_fix_net) {
901
      unrouted_net = routed_net->unrouted_fix_net;
902
/*
903
      printf("  with UNROUTED '%s'\n",unrouted_net->identifier);
904
*/
2 mjames 905
 
11 mjames 906
          if ( unrouted_net->nodecount > 0 && IS_NOT_ROUTABLE(unrouted_net->how_routed))       
907
            /* skip all 1-node nets, these will be dealt with by
908
                                                   a later routing algorithm */
909
            {
2 mjames 910
 
11 mjames 911
            if (routed_net->nodecount >= unrouted_net->nodecount) {
912
                  /* enough nodes, but does it go the right places ?? */
913
                  noderef_t *unrouted_nodes = unrouted_net->nodes;
914
                  noderef_t *routed_nodes = routed_net->nodes;
915
                  clear_routing_flags (routed_nodes);
916
                  while (unrouted_nodes && f)  {
917
                    f = search_net_for_socket (unrouted_nodes,
918
                                                 routed_nodes,1) != NULL;
919
                    unrouted_nodes = unrouted_nodes->next;
920
                    }
921
                  /* if f is 1 then the routed net connects all of the nodes on the
922
                     unrouted net */
923
                  if (f) {
924
                      /* Can join Routed & Unrouted nets together */
925
/*
926
          printf("Managed '%s' for fixed net routing '%s' \n",routed_net -> identifier,
927
                     unrouted_net->identifier);
928
*/
929
                    combine_routed_and_unrouted (routed_net, unrouted_net);
2 mjames 930
 
11 mjames 931
                    /* prevent this net from being recycled, move to
932
                         the fully named and routed list */
933
                    transfer_net_to_named (&routed_list, routed_net);
934
                    routed_net->how_routed = By_Fixed_Net;      /* This net was routed by finding a wire! */
935
                    routed_ok = 1;
936
/*
937
                    Log (LOG_GENERAL, "# Sucessfully routed net '%s' by fixing pins\n", routed_net->name);
938
*/
939
 
940
                    }
941
 
942
 
943
          }
944
            };
945
 
946
          if (routed_ok) {
947
/*      printf("Removing '%s' from list\n",unrouted_net->identifier);
948
*/
949
            /* remove the unrouted net from the list */
950
            remove_net (&unrouted_list, unrouted_net);
951
            }
952
      else
953
        Log(LOG_ERROR,"-- Error (probably) : net '%s':  Fix pin attempt has failed on this net !!\n",unrouted_net->identifier);
954
 
955
          }
956
          routed_net = routed_next;
957
        }
958
  count_nets ("After routing fixed nets");
2 mjames 959
}
960
 
11 mjames 961
 
962
 
963
 
964
 
965
 
2 mjames 966
/* ******************************************** */
967
/* this code deals with trying to find if a Routed net with
968
   exactly the same connections as the Unrouted net exists.
969
   Preference is to be given to any routed nets that have fixed pins */
970
/* ******************************************** */
971
 
11 mjames 972
 
973
 
974
void
975
perform_routing_by_exact_path (void)
2 mjames 976
{
11 mjames 977
  net_t *unrouted_net;
978
  net_t *routed_net;
979
  int routed_ok,f;
980
  enum { CheckFixed,DoAny } pass;
981
 
982
  for(pass=CheckFixed;pass<=DoAny;pass++)
983
    {
2 mjames 984
 
11 mjames 985
    unrouted_net = unrouted_list;
986
    while (unrouted_net) {
987
          routed_ok = 0;
988
      f = 1;
2 mjames 989
 
11 mjames 990
          /* if we are looking for EXACT path matching, then ANY node on the unrouted list
991
             will be connected to the SAME routed net, so just pick the first node        */
2 mjames 992
 
993
 
11 mjames 994
      if (unrouted_net->nodes)
995
             routed_net = unrouted_net->nodes->node->routed_net;
996
          else
997
             routed_net = NULL;
2 mjames 998
 
11 mjames 999
          if (IS_ROUTABLE(unrouted_net->how_routed) &&
1000
          routed_net && /* any nodes ? */
1001
              /* on pass= DoAny, consider all. */
1002
              /* on pass= CheckFixed, only those with a fixed pin on the net */
1003
              (pass==DoAny || (pass==CheckFixed && routed_net->has_fix_location)) &&
1004
 
1005
              routed_net->list_ref == &routed_list && /* is routed net still available on the routed list ? */
1006
              unrouted_net->nodecount > 0)      /* skip all 1-node nets, these will be dealt with by
1007
                                                   a later routing algorithm */
1008
            {
2 mjames 1009
 
11 mjames 1010
              if (routed_net->nodecount >= unrouted_net->nodecount &&
1011
                  IS_ROUTABLE(routed_net->how_routed))
1012
                {
1013
                  /* enough nodes, but does it go the right places ?? */
1014
                  noderef_t *unrouted_nodes = unrouted_net->nodes;
1015
                  noderef_t *routed_nodes = routed_net->nodes;
1016
                  clear_routing_flags (routed_nodes);
1017
                  while (unrouted_nodes && f)
1018
                    {
1019
                      f = search_net_for_socket (unrouted_nodes,
1020
                                                 routed_nodes,1) != NULL;
1021
                      unrouted_nodes = unrouted_nodes->next;
1022
                    }
1023
                  /* if f is 1 then the routed net connects all of the nodes on the
1024
                     unrouted net */
1025
                  if (f)
1026
                    {
1027
                      /* Can join Routed & Unrouted nets together */
1028
/*        printf("Managed '%s' for exact path routing '%s' \n",routed_net -> identifier,
1029
   unrouted_net->identifier);
1030
*/
1031
                      combine_routed_and_unrouted (routed_net, unrouted_net);
1032
 
1033
                      /* prevent this net from being recycled, move to
1034
                         the fully named and routed list */
1035
                      transfer_net_to_named (&routed_list, routed_net);
1036
                      routed_net->how_routed = By_Exact_Net;    /* This net was routed by finding a wire! */
1037
                      routed_ok = 1;
1038
/*
1039
                      Log (LOG_GENERAL, "# Sucessfully routed net '%s' by exact path\n", routed_net->name);
1040
*/
1041
 
1042
                    }
1043
 
1044
 
1045
                }
1046
            };
1047
          if (routed_ok) {
1048
/*      printf("Removing '%s' from list\n",unrouted_net->identifier);
1049
*/
1050
            /* remove the unrouted net from the list */
1051
            unrouted_net = remove_net (&unrouted_list, unrouted_net);}
1052
          else {
1053
 
1054
            /* Not removing net as algorithm hasnt found a match */
1055
            unrouted_net = unrouted_net->next;
1056
            }
1057
      }
1058
    }   /* pass counter loop */                
1059
  count_nets ("After routing by finding exactly identical paths");
1060
 
1061
 
2 mjames 1062
}
1063
 
1064
/* ******************************************** */
11 mjames 1065
void
1066
perform_routing_by_path (void)
2 mjames 1067
{
11 mjames 1068
  net_t *unrouted_net = unrouted_list;
1069
  net_t *routed_net;
1070
  int accept_nodes;
2 mjames 1071
 
1072
 
1073
 
1074
 
11 mjames 1075
  while (unrouted_net)
1076
    {
1077
      int routed_ok = 0;
2 mjames 1078
 
11 mjames 1079
/*
1080
   printf("-- by path : identifier %s\n",unrouted_net->identifier);
1081
 */
1082
      /* repeatedly search the routed nodes list for one with more or the same
1083
         number of connections wanted */
1084
/* skip all 1-node nets, these will be dealt with by a later routing algorithm */
1085
      if (unrouted_net->nodecount > 0 && IS_ROUTABLE(unrouted_net->how_routed))
1086
        {
1087
          for (accept_nodes = unrouted_net->nodecount;
1088
               accept_nodes < MaxNodesForSearch && !routed_ok;
1089
               accept_nodes++)
1090
            {
1091
              /* locate any fix_location nodes here eventually */
1092
              routed_net = routed_list;
1093
 
1094
 
1095
              while (routed_net && !routed_ok)
1096
                {
1097
 
1098
                  if (routed_net->nodecount == accept_nodes &&
1099
                      IS_ROUTABLE(routed_net->how_routed))
1100
                    {
1101
                      /* enough nodes, but does it go the right places ?? */
1102
                      int f = 1;
1103
                      noderef_t *unrouted_nodes = unrouted_net->nodes;
1104
                      noderef_t *routed_nodes = routed_net->nodes;
1105
                      clear_routing_flags (routed_nodes);
1106
                      while (unrouted_nodes && f)
1107
                        {
1108
                          f = search_net_for_socket (unrouted_nodes,
1109
                                                     routed_nodes,1) != NULL;
1110
                          unrouted_nodes = unrouted_nodes->next;
1111
                        }
1112
                      /* if f is 1 then the routed net connects all of the nodes on the
1113
                         unrouted net */
1114
                      if (f)
1115
                        {
1116
                          /* Can join Routed & Unrouted nets together */
1117
                          combine_routed_and_unrouted (routed_net, unrouted_net);
1118
 
1119
                          /* prevent this net from being recycled, move to
1120
                             the fully named and routed list */
1121
                          transfer_net_to_named (&routed_list, routed_net);
1122
                          routed_net->how_routed = By_Net;      /* This net was routed by finding a wire! */
1123
                          routed_ok = 1;
1124
                        }
1125
                    }
1126
                  routed_net = routed_net->next;
1127
                };
1128
            }
1129
        }
1130
      if (routed_ok) {
1131
        /* remove the unrouted net from the list */
1132
        unrouted_net = remove_net (&unrouted_list, unrouted_net);
1133
        }
1134
      else
1135
        /* Not removing net as algorithm hasnt found a match */
1136
        unrouted_net = unrouted_net->next;
1137
    }
1138
 
1139
  count_nets ("After routing by finding existing net paths");
1140
 
1141
 
2 mjames 1142
}
1143
 
11 mjames 1144
 
2 mjames 1145
/* ******************************************** */
1146
/* this function checks all the unrouted nets to see if any of them
1147
   are connected to nodes that are known to exist on a connector, but
1148
   are not on any net. This works to join up unrouted nets mentioned in
1149
   CHIP descriptions */
1150
 
11 mjames 1151
void
1152
perform_routing_by_making_nets (void)
2 mjames 1153
{
11 mjames 1154
  net_t *unrouted_net = unrouted_list;
1155
  net_t *next_net;
1156
  int failcount = 0;
1157
  while (unrouted_net)
1158
    {
1159
      int routed_ok = 0;
1160
      int f = 1;
1161
      noderef_t *unrouted_nodes;
1162
      next_net = unrouted_net->next;
1163
      if(IS_ROUTABLE(unrouted_net->how_routed))  {
1164
        unrouted_nodes = unrouted_net->nodes;
2 mjames 1165
 
11 mjames 1166
/*
1167
   printf("-- by making nets : identifier %s\n",unrouted_net->identifier);
1168
 */
1169
      /* repeatedly search the unrouted net list */
1170
      /* only route unconnected nodes referred to by one net,
1171
         whether routed or unrouted otherwise shorts will happen */
1172
      while (IS_ROUTABLE(unrouted_net->how_routed) &&
1173
             unrouted_nodes &&
1174
             ((f = unrouted_nodes->node->net_assigned == 0) &&
1175
              unrouted_nodes->node->refcount == 1))
1176
        unrouted_nodes = unrouted_nodes->next;
1177
      if (!f && unrouted_nodes)
1178
        {
1179
          failcount++;
1180
          Log (LOG_ERROR, "-- FAIL on : net %s\n", unrouted_net->identifier);
1181
          Log (LOG_ERROR, "--   node %s(%s)\n",
1182
               unrouted_nodes->node->socket->identifier,
1183
               unrouted_nodes->node->identifier);
1184
          if (unrouted_nodes->node->net_assigned)
1185
            Log (LOG_ERROR, "-- Node is on an already assigned net\n");
1186
          if (unrouted_nodes->node->refcount > 1)
1187
            Log (LOG_ERROR, "-- Node is referred to by %d nets\n",
1188
                 unrouted_nodes->node->refcount);
1189
        }
2 mjames 1190
 
1191
 
11 mjames 1192
      /* if f is 1 then the unrouted net contains only unassigned nodes */
1193
      if (f)
1194
            {
1195
        net_t *poss_routed_net;
1196
        /* now we need to confirm that the name is unique:
1197
           search for it to see if there already*/
1198
        poss_routed_net = find_net (&routed_list, Ident, unrouted_net->identifier, Search);
1199
        if (!poss_routed_net ) { /* its unique */
1200
              /* prevent this net from being recycled, move to
1201
                the fully named and routed list */
1202
              combine_routed_and_unrouted (unrouted_net, unrouted_net);
1203
              transfer_net_to_named (&unrouted_list, unrouted_net);
1204
              unrouted_net->how_routed = By_Creating;   /* This net was routed by creating a new one !! */
1205
              Log (LOG_GENERAL, "-- Info: Created Wiring for net '%s'\n",unrouted_net->identifier);
1206
              routed_ok = 1;
1207
          }
1208
        else {
1209
              Log (LOG_ERROR, "-- ERROR: Net identifier '%s' already in use in routed list: cannot create\n",unrouted_net->identifier);
1210
              routed_ok = 0;
1211
          }
1212
 
1213
           }
1214
      }
1215
      /* move on , either its been moved from one list to the other or its still there */
1216
      unrouted_net = next_net;
1217
    }
1218
 
1219
  count_nets ("After routing by making nets");
1220
 
1221
 
2 mjames 1222
}
1223
 
11 mjames 1224
 
1225
 
1226
 
1227
 
1228
 
1229
 
2 mjames 1230
/* ******************************************** */
1231
/* Pruning nets that have names like rsv00000z  */
1232
/* from a list                                  */
1233
/* ******************************************** */
1234
 
11 mjames 1235
void prune_nets_from_list (net_t ** list, char *res_tpl)
2 mjames 1236
{
11 mjames 1237
  net_t *curr_net = *list;
1238
  while (curr_net)
1239
    {
1240
      int i = 0;
1241
      while ((i < RES_NAMLEN) &&
1242
      /* string match */
1243
             (res_tpl[i] == tolower(curr_net->identifier[i]) ||
1244
      /* 0 in template matches a digit */
1245
              ((res_tpl[i] == '0') && isdigit (curr_net->identifier[i]))))
1246
        i++;
1247
      if (i == RES_NAMLEN)
1248
        curr_net = remove_net (list, curr_net);
1249
      else
1250
        curr_net = curr_net->next;
1251
    }
2 mjames 1252
}
1253
 
1254
/* ******************************************** */
1255
 
11 mjames 1256
 
1257
void
1258
prune_nets ()
2 mjames 1259
{
11 mjames 1260
  char res_tpl[RES_NAMLEN + 1];
1261
  sprintf (res_tpl, RES_FMT, 0);        /* create a template, with 00000 in it  */
1262
  prune_nets_from_list (&routed_list, res_tpl);
1263
  prune_nets_from_list (&unrouted_list, res_tpl);
2 mjames 1264
 
11 mjames 1265
  count_nets ("After deleting dummy nets e.g. 'rsv00001z'");
2 mjames 1266
}
1267
 
11 mjames 1268
 
1269
 
2 mjames 1270
/* ******************************************** */
1271
/* this function is intended to check to see how many nets have got
1272
   how_routed = By_FixPins .  */
1273
 
11 mjames 1274
void
1275
check_for_unused_fixed_nets (char * why)
2 mjames 1276
{
11 mjames 1277
  net_t *curr_net = routed_list;
1278
  int print_flag=1;
1279
  while (curr_net)
1280
    {
1281
    if (curr_net->how_routed == By_FixPins) {
1282
      if(print_flag) {
1283
        print_flag=0;
1284
        Log (LOG_ERROR, "-- ERROR : fix_pin fails due to %s:\n-- Failures :\n",why);
1285
        }    
1286
          Log (LOG_ERROR, "--   '%s' to routed net='%s'\n", curr_net->name, curr_net->identifier);
1287
      }
1288
    curr_net = curr_net->next;
1289
    }
1290
  puts ("--");
2 mjames 1291
}
1292
 
11 mjames 1293
 
1294
 
2 mjames 1295
/* ******************************************** */
1296
 
11 mjames 1297
void
1298
perform_routing (HowRouted_t how)
2 mjames 1299
{
1300
 
11 mjames 1301
  count_nets("Before fixing up pin aliases");
1302
 
1303
  create_unrouted_list();
2 mjames 1304
 
11 mjames 1305
  if (need_validate_names) {
1306
    Log(LOG_GENERAL,"# Validating net names and identifiers\n");
1307
    validate_names();
1308
    need_validate_names = 0;
1309
    }
1310
  count_nets ("Before routing");
1311
  validate_unrouted();
2 mjames 1312
 
11 mjames 1313
  prune_nets ();
2 mjames 1314
 
11 mjames 1315
 
1316
  if (how == Free || how == By_Name)
1317
    {
1318
/* get rid of all unrouted nets that have been invented in the first place */
1319
      perform_routing_by_name ();
1320
      check_for_unused_fixed_nets ("Nets already routed by name");
1321
    };
1322
  if (how == Free || how == By_Fixed_Net)
1323
    {
1324
      perform_routing_by_fixed_net ();
1325
      check_for_unused_fixed_nets ("Routed nets with fixed pins do not match unrouted");
1326
    };
1327
  if (how == Free || how == By_Exact_Net)
1328
    perform_routing_by_exact_path ();
1329
  if (how == Free || how == By_Net)
1330
    perform_routing_by_path ();
1331
  if (how == By_Creating)  /* Will not  create missing nets !! : use creation */
1332
    perform_routing_by_making_nets ();
1333
  if(how==Free )
1334
    ensure_reservation();
1335
  count_nets_with_few_nodes(1); /* summarise single connection nets */
2 mjames 1336
}
1337
 
11 mjames 1338
 
2 mjames 1339
/* ******************************************** */
1340
/* Experimental bit of code : For all nets that connect to
1341
   a pin of an external socket in the unrouted list ,
1342
   check to see if the routed net connected to the same pin has a name assigned.
1343
   If it does not then try setting the name of the net to the identifier
1344
   of the unrouted net . Use this before routing */
1345
 
11 mjames 1346
 
1347
void
1348
perform_trial_naming (void)
2 mjames 1349
{
11 mjames 1350
  net_t *cur_net ;
1351
  int fixed_counter = 0 ;
1352
 
1353
  create_unrouted_list();
2 mjames 1354
 
11 mjames 1355
  cur_net = unrouted_list; /* after pin renames etc have been executed */
2 mjames 1356
 
11 mjames 1357
  prune_nets(); /* will not fix rsv00000z pins !! */
2 mjames 1358
 
11 mjames 1359
  while (cur_net)
1360
    {
1361
      noderef_t *nodes = cur_net->nodes;
1362
      if (level & 8)
1363
            Log (LOG_GENERAL, "# Trying to fix net '%s'\n",
1364
                       cur_net->identifier);
1365
      while (nodes)
1366
        {
1367
          /* is this node pointing at an external socket */
1368
          node_t *n = nodes->node;
1369
          /* only fix one routed net to this un_routed net */
1370
          if (n->socket->is_external)
1371
            {   /* on an external socket */
2 mjames 1372
 
11 mjames 1373
                  n->fix_location = 1;  /* set the location fixed flag a*/
1374
                  if(n->routed_net) {   /* and set the flag on the routed net */
1375
                    n->routed_net->unrouted_fix_net = cur_net;
1376
                    n->routed_net->has_fix_location = 1;
1377
            fixed_counter++;
1378
            if (level & 8)
1379
                  Log (LOG_GENERAL, "#    to net '%s'\n",
1380
                         n->routed_net->identifier);
1381
                  }
1382
            }
1383
          nodes = nodes->next;
1384
        }
1385
/*
1386
          Log (LOG_GENERAL, "#\n");
1387
*/
1388
      cur_net = cur_net->next;
1389
    }
1390
        Log (LOG_GENERAL, "# Fixed %d pins\n",
1391
                       fixed_counter);
2 mjames 1392
}
1393
 
11 mjames 1394
 
1395
 
1396
 
1397
 
2 mjames 1398
/* ********************************************************************* */
1399
 
1400
/* force routing flag of routed net  */
11 mjames 1401
void force_route(char * template,HowRouted_t flag)
1402
  {
1403
  net_t * net = routed_list;
1404
  int rc,any_found =0;
1405
  int found;
2 mjames 1406
 
11 mjames 1407
  /* compile regular expression */
1408
  vert_regex_t * preg;
2 mjames 1409
 
11 mjames 1410
  rc = vert_regcomp(&preg,template);
2 mjames 1411
 
11 mjames 1412
  if (rc != 0 )
1413
    {
1414
    char errbuff[100];
1415
    regerror(rc,preg->preg,errbuff,100);
1416
    Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,template);
1417
 
1418
/*    return TCL_ERROR;
1419
*/
1420
    return;
1421
    }
1422
  else
1423
    {
1424
    Log(LOG_GENERAL,"-- Using '%s' as match pattern\n",template);
1425
    }
2 mjames 1426
 
11 mjames 1427
  while(net) {
1428
    found  = regexec(preg->preg,net->identifier,0,preg->regpatt,0);
1429
 
1430
    if(!found) {
1431
      char * s;
1432
      any_found = 1;
1433
      net->how_routed = flag;
1434
      switch(flag)
2 mjames 1435
        {
11 mjames 1436
        case Not_Routable  : s="not routable";   break;
1437
        case Not_Routable_H: s="not routable H"; break;
1438
        case Not_Routable_L: s="not routable L"; break;
1439
        default            : s="routable";       break;
2 mjames 1440
        }
11 mjames 1441
      Log(LOG_GENERAL,"-- Set net '%s' as %s\n",net->identifier,s);
1442
      }
1443
    net = net->next;
1444
    }
1445
  if(!any_found)
1446
      Log(LOG_GENERAL,"-- No nets match '%s'\n",template);
1447
  vert_regfree(&preg);
1448
  }
1449
 
2 mjames 1450
 
1451
/* ********************************************************************* */
11 mjames 1452
void set_group_route_flags(char * template,int flag)
2 mjames 1453
{
11 mjames 1454
  int found;
1455
  socket_t * socket = socket_head;
1456
  int rc,any_found =0;
2 mjames 1457
 
11 mjames 1458
  /* compile regular expression */
1459
  vert_regex_t  * preg;
1460
  rc = vert_regcomp(&preg,template);
2 mjames 1461
 
11 mjames 1462
  if (rc != 0 )
1463
    {
1464
    char errbuff[100];
1465
    regerror(rc,preg->preg,errbuff,100);
1466
    Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,template);
1467
 
1468
/*    return TCL_ERROR;
1469
*/
1470
    return;
1471
    }
1472
  else
1473
    {
1474
    Log(LOG_GENERAL,"-- Using '%s' as match pattern\n",template);
1475
    }
2 mjames 1476
 
11 mjames 1477
  Log(LOG_GENERAL,"----- Setting pin group routing flags to %d for\n",flag);
1478
 
1479
  while(socket ) {
1480
    found  = regexec(preg->preg,socket->identifier,0,preg->regpatt,0);
1481
    if(!found) {
1482
      any_found = 1;
1483
      socket->route_flags = flag;
1484
      Log(LOG_GENERAL,"-- socket '%s'\n",socket->identifier);
1485
      }
1486
    socket = socket->next;
1487
    }
1488
  if(!any_found)
1489
      Log(LOG_GENERAL,"-- No sockets match '%s'\n",template);
1490
  vert_regfree(&preg);
1491
  }
2 mjames 1492
 
1493
 
1494
/**************************************************************/
11 mjames 1495
/* Function sets the pin group flags on a device */
2 mjames 1496
/* pattern is ic.pin                             */
1497
/* changed to ic(pin)                            */
11 mjames 1498
void set_pin_group_flags (char * device_string,int flag) {
1499
  socket_t * socket;
1500
  node_t * node;
1501
  int socket_cnt=0,pin_cnt=0; /* counters */
1502
  int found_socket,found_pin;
1503
  char * s = strdup(device_string);
1504
  char * p, *q;
1505
  int rc;
1506
  /* compile regular expression */
1507
  vert_regex_t * skt_reg, * pin_reg;
2 mjames 1508
 
1509
 
1510
 
11 mjames 1511
 
1512
/* find the '(' in the socket name  name */
2 mjames 1513
 
11 mjames 1514
  p = strchr(s,'(');
1515
  q = strrchr(s,')');
1516
  if(p==s)
1517
    {
1518
    s= ".*"; /* wildcard for chip id */
1519
    }
1520
  if (!p || !q || q<p)
1521
    {
1522
    p = ".*"; /* wilcard for pin id */
1523
    }
1524
  else
1525
    {
1526
    *p++ = 0;
1527
    *q   = 0;
1528
    }
2 mjames 1529
 
11 mjames 1530
  rc = vert_regcomp(&skt_reg,s);
2 mjames 1531
 
11 mjames 1532
  if (rc != 0 )
1533
    {
1534
    char errbuff[100];
1535
    regerror(rc,skt_reg->preg,errbuff,100);
1536
    Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,s);
1537
 
1538
/*    return TCL_ERROR;
1539
*/
1540
    return;
1541
    }
1542
  else
1543
    {
1544
    Log(LOG_GENERAL,"-- Using '%s' as socket match pattern\n",s);
1545
    }
2 mjames 1546
 
11 mjames 1547
  rc = vert_regcomp(&pin_reg,p);
2 mjames 1548
 
11 mjames 1549
  if (rc != 0 )
1550
    {
1551
    char errbuff[100];
1552
    regerror(rc,pin_reg->preg,errbuff,100);
1553
    Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,p);
1554
 
1555
/*    return TCL_ERROR;
1556
*/
1557
    return;
1558
    }
1559
  else
1560
    {
1561
    Log(LOG_GENERAL,"-- Using '%s' as socket match pattern\n",p);
1562
    }
2 mjames 1563
 
1564
 
11 mjames 1565
  socket = socket_head;
1566
  while(socket)
1567
    {
1568
    found_socket  = regexec(skt_reg->preg,socket->identifier,0,skt_reg->regpatt,0);
1569
    if(!found_socket) {
1570
      socket_cnt ++;
1571
      node = socket->nodes;
1572
/*
1573
      Log(LOG_GENERAL,"-- Chip ID %s\n",socket->identifier);
1574
*/
1575
      found_pin = 0;
1576
      while(node) {
1577
        found_pin  = regexec(pin_reg->preg,node->identifier,0,pin_reg->regpatt,0);
2 mjames 1578
 
11 mjames 1579
        if(!found_pin) {
1580
/*
1581
          Log(LOG_GENERAL,"-- Pin %s.%s\n",socket->identifier,node->identifier);
1582
*/
1583
          pin_cnt ++;
1584
          node->pin_group = flag;
1585
          }
1586
        node = node->sktnext;
1587
        }    
1588
      }
1589
    socket = socket->next;
1590
    }
1591
  if(socket_cnt)
1592
    Log(LOG_GENERAL,"-- Checked %d sockets\n",socket_cnt);
1593
  if(pin_cnt)  
1594
    Log(LOG_GENERAL,"-- Set pin group to %d on a total of %d pins\n",
1595
       flag,pin_cnt);
1596
  else
1597
    Log(LOG_GENERAL,"-- Did not locate any pins matching pattern\n");
1598
 
1599
  vert_regfree(&pin_reg);
1600
  vert_regfree(&skt_reg);
1601
 
1602
  }