Subversion Repositories Vertical

Rev

Rev 2 | 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 Exp $
  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
  92.  *
  93.  * Revision 1.57  2000/10/04  10:37:09  10:37:09  mjames (Mike James)
  94.  * Part of Release PSAVAT01
  95.  *
  96.  * Revision 1.56  2000/10/02  11:04:20  11:04:20  mjames (Mike James)
  97.  * new_vhdl
  98.  *
  99.  * Revision 1.55  2000/09/27  14:42:20  14:42:20  mjames (Mike James)
  100.  * Part of Release Sep_27_ST_2000
  101.  *
  102.  * Revision 1.54  2000/09/21  10:15:50  10:15:50  mjames (Mike James)
  103.  * Part of Release Sep21Alpha
  104.  *
  105.  * Revision 1.53  2000/08/25  09:57:16  09:57:16  mjames (Mike James)
  106.  * Part of Release Aug25_alpha
  107.  *
  108.  * Revision 1.52  2000/08/16  08:57:32  08:57:32  mjames (Mike James)
  109.  * Part of Release CD01_Aug2000
  110.  *
  111.  * Revision 1.51  2000/08/16  08:55:43  08:55:43  mjames (Mike James)
  112.  * corrected routing/unroutable nets errors
  113.  *
  114.  * Revision 1.50  2000/08/14  14:45:13  14:45:13  mjames (Mike James)
  115.  * Part of Release Aug_14_2000
  116.  *
  117.  * Revision 1.49  2000/08/14  14:43:31  14:43:31  mjames (Mike James)
  118.  * Added power pins
  119.  *
  120.  * Revision 1.48  2000/08/11  08:30:33  08:30:33  mjames (Mike James)
  121.  * Part of Release Aug_11_2000
  122.  *
  123.  * Revision 1.47  2000/08/09  10:31:49  10:31:49  mjames (Mike James)
  124.  * Part of Release Aug_9_2000
  125.  *
  126.  * Revision 1.46  2000/05/31  11:43:00  11:43:00  mjames (Mike James)
  127.  * Part of Release May_31_2000
  128.  *
  129.  * Revision 1.45  2000/05/08  17:01:39  17:01:39  mjames (Mike James)
  130.  * Part of Release May_8_2000
  131.  *
  132.  * Revision 1.44  2000/05/08  16:59:32  16:59:32  mjames (Mike James)
  133.  * Part of Release May_8_2000
  134.  *
  135.  * Revision 1.43  2000/05/08  16:57:09  16:57:09  mjames (Mike James)
  136.  * Part of Release May_8_2000
  137.  *
  138.  * Revision 1.42  2000/03/08  16:19:29  16:19:29  mjames (Mike James)
  139.  * New version including PC
  140.  *
  141.  * Revision 1.39  2000/01/20  15:58:50  15:58:50  mjames (Mike James)
  142.  * Part of Release R22
  143.  *
  144.  * Revision 1.38  99/12/22  11:15:30  11:15:30  mjames (Mike James)
  145.  * Part of Release Dec_22_1999
  146.  *
  147.  * Revision 1.37  99/06/25  14:35:50  14:35:50  mjames (Mike James)
  148.  * Added in reference to expression.h, but no changes made
  149.  * to the function of acfread yet.
  150.  *
  151.  * Revision 1.36  99/06/18  09:26:23  09:26:23  mjames (Mike James)
  152.  *
  153.  * Revision 1.35  99/05/04  09:52:46  09:52:46  mjames (Mike James)
  154.  * General checkin
  155.  *
  156.  * Revision 1.33  98/11/27  15:16:05  15:16:05  mjames (Mike James)
  157.  * FIxed small errors
  158.  *
  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
  162.  *
  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.
  166.  *
  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.
  171.  *
  172.  * Revision 1.29  98/02/11  11:27:14  11:27:14  mjames (Mike James)
  173.  * Checked in for version 6.2a
  174.  *
  175.  * Revision 1.28  97/04/23  08:43:23  08:43414:23  mjames (Mike James)
  176.  * CHecked in for release rel23041997
  177.  *
  178.  * Revision 1.27  97/01/03  13:35:24  13:35:24  mjames (Mike James)
  179.  * Tidied up the ensure_reserved() function. Added in a flag to
  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
  184.  *
  185.  * Revision 1.26  96/12/23  15:14:38  15:14:38  mjames (Mike James)
  186.  * This code for fixing pins has been split from the 'exact path'
  187.  * routing as the algorithm has become more reliable
  188.  * if there are two independednt routines.
  189.  *
  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
  192.  *
  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.  
  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>
  269.  
  270. #include "vertcl_main.h"
  271. #include "expression.h"
  272. #include "generic.h"
  273. #include "database.h"
  274. #include "lx_support.h"
  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"
  281. #include "sorting.h"
  282.  
  283. #ident "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/routing.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $"
  284.  
  285.  
  286.  
  287. /* used in search for pre-existing path */
  288. int MaxNodesForSearch = MAX_NODES_FOR_PATH_SEARCH;
  289.  
  290.  
  291. int global_group_flag = 0 ;
  292.  
  293. static void
  294. get_num_nets (net_t * list, char *message)
  295. {
  296.   int i = 0;
  297.   while (list)
  298.     {
  299.       list = list->next;
  300.       i++;
  301.     }
  302.   Log (LOG_GENERAL, "-- %-4d %s\n", i, message);
  303. }
  304.  
  305. void
  306. count_nets (char *message)
  307. {
  308.  
  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.  
  316. }
  317.  
  318.  
  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  */
  324. void clear_routing_flags(noderef_t * net_nodes)
  325. {
  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.  
  333. }
  334.  
  335.  
  336.  
  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 */
  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;
  350.  
  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;
  371. }
  372.  
  373.  
  374. /* removes a net from the list of nets */
  375.  
  376. net_t *remove_net (net_t ** list, net_t * net)
  377. {
  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.     };
  400.  
  401.  
  402.   /* get pointer to the nodes on this net */
  403.   refs = net->nodes;
  404.  
  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]";
  415.  
  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;
  428. }
  429.  
  430.  
  431. /* moves a net from one list to another */
  432. void
  433. transfer_net_to_named (net_t ** from_list,
  434.                        net_t * net)
  435. {
  436.  
  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;
  445.  
  446.  
  447.   if (net == *from_list)
  448.     *from_list = net->next;
  449.  
  450.   net->list_ref = &named_list;  /* net now is on the named list */
  451.  
  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.  
  465. }
  466.  
  467.  
  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.  
  480. /* the dummy node count is external to the naming routine, as it
  481.    is used in the ensure_reservation code */
  482.   static int nodecount = 0;
  483.  
  484. void
  485. name_unused_nodes (net_t * routed_net,
  486.                    char *identifier)
  487. {
  488.   noderef_t *routed_nodes;
  489.   char *unused_ident;
  490.  
  491.  
  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 */
  504.  
  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;
  511.  
  512.               cnode->orig_vhdltype = NULL;      /* put something there */
  513.  
  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.     }
  533. }
  534.  
  535. /* ******************************************** */
  536. /* connect up the routed and  unrouted nets */
  537.  
  538. void
  539. combine_sub (net_t * routed_net,
  540.              net_t * unrouted_net)
  541. {
  542.   noderef_t *routed_nodes, *unrouted_nodes;
  543.  
  544. /*
  545.    printf("-- Moving net %s onto routing of %s\n",
  546.    unrouted_net->identifier,routed_net->identifier);
  547.  */
  548.  
  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;
  564.  
  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 */
  568.  
  569. /* Changed MDJ July 2001 : made it a prerequisite to check if the pin_group matches */
  570.  
  571.       route_ref = search_net_for_socket (unrouted_nodes, routed_nodes,unrouted_node->pin_group);
  572.  
  573.  
  574.  
  575.  
  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.  
  625. }
  626.  
  627.  
  628.  
  629. static void
  630. combine_alias (net_t * routed_net,
  631.                net_t * unrouted_net)
  632. {
  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.  
  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.  
  660. void
  661. combine_routed_and_unrouted (net_t * routed_net,
  662.                              net_t * unrouted_net)
  663. {
  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; */
  674.  
  675.   routed_net->vhdltype = unrouted_net->vhdltype;
  676.  
  677.  
  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.      }
  692. }
  693.  
  694.  
  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 */
  700.    
  701. void
  702. ensure_reservation (void)
  703. {
  704.   char *unused_ident;
  705.   net_t * net_head = routed_list;
  706.   int skip; /* the number of nodes on the net to leave unreserved */
  707.  
  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 */
  734.  
  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.           {
  753. /*
  754.           transfer_net_to_named (&routed_list, altered_net);
  755. */    }
  756.     }
  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. {
  763.   net_t *routed_net, *unrouted_net;
  764.  
  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);
  770.  
  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.                      
  786.         }
  787.       else
  788.         unrouted_net -> how_routed = Free; /* can keep on routing this net */
  789.       }
  790.     unrouted_net = unrouted_net->next;
  791.     }
  792.   }
  793.    
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.  
  801.  
  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 */
  809. void
  810. perform_routing_by_name (void)
  811. {
  812.   net_t *routed_net;
  813.   noderef_t *routed_nodes, *unrouted_nodes;
  814.   net_t *unrouted_net, *prev_net;
  815.   int routed_ok;
  816.  
  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 */
  825.  
  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);
  829.  
  830.  
  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);
  842.  
  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");
  875. }
  876.  
  877.  
  878.  
  879. /************************************************************************/
  880. /* this algorithm works by considering each of the routed nets in turn
  881.    to see if there is an unrouted net 'fixed' to it. */
  882. /************************************************************************/
  883.    
  884. void
  885. perform_routing_by_fixed_net(void)
  886. {
  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. */
  905.  
  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.             {
  910.  
  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);
  930.  
  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");
  959. }
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  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.  
  972.  
  973.  
  974. void
  975. perform_routing_by_exact_path (void)
  976. {
  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.     {
  984.  
  985.     unrouted_net = unrouted_list;
  986.     while (unrouted_net) {
  987.           routed_ok = 0;
  988.       f = 1;
  989.  
  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        */
  992.  
  993.  
  994.       if (unrouted_net->nodes)
  995.              routed_net = unrouted_net->nodes->node->routed_net;
  996.           else
  997.              routed_net = NULL;
  998.  
  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.             {
  1009.  
  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.  
  1062. }
  1063.  
  1064. /* ******************************************** */
  1065. void
  1066. perform_routing_by_path (void)
  1067. {
  1068.   net_t *unrouted_net = unrouted_list;
  1069.   net_t *routed_net;
  1070.   int accept_nodes;
  1071.  
  1072.  
  1073.  
  1074.  
  1075.   while (unrouted_net)
  1076.     {
  1077.       int routed_ok = 0;
  1078.  
  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.  
  1142. }
  1143.  
  1144.  
  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.  
  1151. void
  1152. perform_routing_by_making_nets (void)
  1153. {
  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;
  1165.  
  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.         }
  1190.  
  1191.  
  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.  
  1222. }
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.  
  1230. /* ******************************************** */
  1231. /* Pruning nets that have names like rsv00000z  */
  1232. /* from a list                                  */
  1233. /* ******************************************** */
  1234.  
  1235. void prune_nets_from_list (net_t ** list, char *res_tpl)
  1236. {
  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.     }
  1252. }
  1253.  
  1254. /* ******************************************** */
  1255.  
  1256.  
  1257. void
  1258. prune_nets ()
  1259. {
  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);
  1264.  
  1265.   count_nets ("After deleting dummy nets e.g. 'rsv00001z'");
  1266. }
  1267.  
  1268.  
  1269.  
  1270. /* ******************************************** */
  1271. /* this function is intended to check to see how many nets have got
  1272.    how_routed = By_FixPins .  */
  1273.  
  1274. void
  1275. check_for_unused_fixed_nets (char * why)
  1276. {
  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 ("--");
  1291. }
  1292.  
  1293.  
  1294.  
  1295. /* ******************************************** */
  1296.  
  1297. void
  1298. perform_routing (HowRouted_t how)
  1299. {
  1300.  
  1301.   count_nets("Before fixing up pin aliases");
  1302.  
  1303.   create_unrouted_list();
  1304.  
  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();
  1312.  
  1313.   prune_nets ();
  1314.  
  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 */
  1336. }
  1337.  
  1338.  
  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.  
  1346.  
  1347. void
  1348. perform_trial_naming (void)
  1349. {
  1350.   net_t *cur_net ;
  1351.   int fixed_counter = 0 ;
  1352.  
  1353.   create_unrouted_list();
  1354.  
  1355.   cur_net = unrouted_list; /* after pin renames etc have been executed */
  1356.  
  1357.   prune_nets(); /* will not fix rsv00000z pins !! */
  1358.  
  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 */
  1372.  
  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);
  1392. }
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398. /* ********************************************************************* */
  1399.  
  1400. /* force routing flag of routed net  */
  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;
  1406.  
  1407.   /* compile regular expression */
  1408.   vert_regex_t * preg;
  1409.  
  1410.   rc = vert_regcomp(&preg,template);
  1411.  
  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.     }
  1426.  
  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)
  1435.         {
  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;
  1440.         }
  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.  
  1450.  
  1451. /* ********************************************************************* */
  1452. void set_group_route_flags(char * template,int flag)
  1453. {
  1454.   int found;
  1455.   socket_t * socket = socket_head;
  1456.   int rc,any_found =0;
  1457.  
  1458.   /* compile regular expression */
  1459.   vert_regex_t  * preg;
  1460.   rc = vert_regcomp(&preg,template);
  1461.  
  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.     }
  1476.  
  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.   }
  1492.  
  1493.  
  1494. /**************************************************************/
  1495. /* Function sets the pin group flags on a device */
  1496. /* pattern is ic.pin                             */
  1497. /* changed to ic(pin)                            */
  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;
  1508.  
  1509.  
  1510.  
  1511.  
  1512. /* find the '(' in the socket name  name */
  1513.  
  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.     }
  1529.  
  1530.   rc = vert_regcomp(&skt_reg,s);
  1531.  
  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.     }
  1546.  
  1547.   rc = vert_regcomp(&pin_reg,p);
  1548.  
  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.     }
  1563.  
  1564.  
  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);
  1578.  
  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.   }
  1603.