Subversion Repositories Vertical

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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