Subversion Repositories Vertical

Rev

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

  1. /*
  2.  * $Id: partition.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $
  3.  *
  4.  * $Log: partition.c,v $
  5.  * Revision 1.1.1.1  2003/11/04 23:34:57  mjames
  6.  * Imported into local repositrory
  7.  *
  8.  * Revision 1.15  2003/01/02 21:37:16  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.14  2002/09/30 13:20:29  MJAMES
  17.  * Modified partition rules to include 'default assignment on declaration'
  18.  * which maps to inputs being driven with default values on
  19.  * productuion of a partition.
  20.  *
  21.  * signal c : std_logic := '0';
  22.  *
  23.  * becomes
  24.  *
  25.  * signal c: std_logic;
  26.  *
  27.  * begin
  28.  *   c<= '0';
  29.  *
  30.  * Revision 1.13  2002/09/18 08:51:24  mjames
  31.  * Removed unused variables
  32.  *
  33.  * Revision 1.12  2002/09/09 10:13:09  mjames
  34.  * Moved pin remapping function to pin ident editing function from
  35.  * sorting pin name routine.
  36.  *
  37.  * Revision 1.11  2002/01/16 11:22:47  mjames
  38.  * database.h header file is read in first as it undefined DLL stuff irrelevant
  39.  * to HPUX
  40.  *
  41.  * Revision 1.10  2001/12/13 22:17:28  mjames
  42.  * Using #ident with header to identify file
  43.  *
  44.  * removed debug messages
  45.  *
  46.  * Revision 1.9  2001/10/31 22:20:11  mjames
  47.  * Tidying up problematical comments caused by CVS
  48.  * 'intelligent' comment guessing
  49.  *
  50.  * Revision 1.8  2001/10/31 16:21:46  mjames
  51.  * Added a datastructure to hide regular expression information from programs.
  52.  * Changed call to regexec to indicate 0 subexpressions to be matched
  53.  * rather than a number dependent on strlen(string) which was wrong.
  54.  * Altered diagnostics while debugging checked in because useful at other
  55.  * times
  56.  *
  57.  * Revision 1.7  2001/10/10 20:18:23  mjames
  58.  * Added a vert_regcomp function to compile regular expressions
  59.  * with '^' (match start string) and  '$' (match end string) bracketing
  60.  * this => wildcard must match entire string not just a part of it.
  61.  *
  62.  * Revision 1.6  2001/10/07 20:50:53  mjames
  63.  * Added wildcard checking (warn user about
  64.  * using wildcard '*' on the end of a string in stead of wildcard '.*')
  65.  *
  66.  * Revision 1.5  2001/09/25 23:24:18  mjames
  67.  * Update because  wildcard behaviour amended
  68.  *
  69.  * Revision 1.4  2001/08/01 07:38:03  mjames
  70.  * Removed multiple informational messages
  71.  * replaced with summary unless debug level is higher
  72.  *
  73.  * Revision 1.3  2001/06/06 12:10:19  mjames
  74.  * Move from HPUX
  75.  *
  76.  * Revision 1.2  2000/11/29 21:51:18  mjames
  77.  * Fine tuning of software
  78.  *
  79.  * Revision 1.1.1.1  2000/10/19 21:58:38  mjames
  80.  * Mike put it here
  81.  *
  82.  *
  83.  * Revision 1.36  2000/10/12  15:32:31  15:32:31  mjames (Mike James)
  84.  * Removed <cr>
  85.  *
  86.  * Revision 1.35  2000/10/12  14:25:49  14:25:49  mjames (Mike James)
  87.  * removed <cr>
  88.  *
  89.  * Revision 1.34  2000/10/04  10:37:07  10:37:07  mjames (Mike James)
  90.  * Modified for Vertical2 : support COMPONENTS and SIGNALS
  91.  *
  92.  * Revision 1.34  2000/10/04  10:37:07  10:37:07  mjames (Mike James)
  93.  * Part of Release PSAVAT01
  94.  *
  95.  * Revision 1.33  2000/10/03  10:05:31  10:05:31  mjames (Mike James)
  96.  * Added CONSTANTS and SIGNALS to architecture
  97.  *
  98.  * Revision 1.31  2000/09/27  14:42:17  14:42:17  mjames (Mike James)
  99.  * Part of Release Sep_27_ST_2000
  100.  *
  101.  * Revision 1.30  2000/09/21  10:15:48  10:15:48  mjames (Mike James)
  102.  * Part of Release Sep21Alpha
  103.  *
  104.  * Revision 1.29  2000/08/25  09:57:13  09:57:13  mjames (Mike James)
  105.  * Part of Release Aug25_alpha
  106.  *
  107.  * Revision 1.28  2000/08/16  08:57:30  08:57:30  mjames (Mike James)
  108.  * Part of Release CD01_Aug2000
  109.  *
  110.  * Revision 1.27  2000/08/14  14:45:11  14:45:11  mjames (Mike James)
  111.  * Part of Release Aug_14_2000
  112.  *
  113.  * Revision 1.26  2000/08/11  08:30:32  08:30:32  mjames (Mike James)
  114.  * Part of Release Aug_11_2000
  115.  *
  116.  * Revision 1.25  2000/08/09  10:31:46  10:31:46  mjames (Mike James)
  117.  * Part of Release Aug__9_2000
  118.  *
  119.  * Revision 1.24  2000/05/31  11:42:56  11:42:56  mjames (Mike James)
  120.  * Part of Release May_31_2000
  121.  *
  122.  * Revision 1.23  2000/05/31  11:30:18  11:30:18  mjames (Mike James)
  123.  * Added acfread.ini file reading
  124.  *
  125.  * Revision 1.22  2000/05/08  17:01:37  17:01:37  mjames (Mike James)
  126.  * Part of Release May__8_2000
  127.  *
  128.  * Revision 1.21  2000/05/08  16:59:30  16:59:30  mjames (Mike James)
  129.  * Part of Release May__8_2000
  130.  *
  131.  * Revision 1.20  2000/05/08  16:57:07  16:57:07  mjames (Mike James)
  132.  * Part of Release May__8_2000
  133.  *
  134.  * Revision 1.19  2000/03/08  16:19:20  16:19:20  mjames (Mike James)
  135.  * New version including PC
  136.  *
  137.  * Revision 1.16  2000/01/20  15:58:47  15:58:47  mjames (Mike James)
  138.  * Part of Release R22
  139.  *
  140.  * Revision 1.15  99/12/22  11:15:27  11:15:27  mjames (Mike James)
  141.  * Part of Release Dec_22_1999
  142.  *
  143.  * Revision 1.14  99/11/23  13:52:12  13:52:12  mjames (Mike James)
  144.  * Addded syntax to support special generics for Certify support
  145.  *
  146.  * Revision 1.13  99/06/25  14:35:46  14:35:46  mjames (Mike James)
  147.  * Added in reference to expression.h, but no changes made
  148.  * to the function of acfread yet.
  149.  *
  150.  * Revision 1.12  99/06/18  09:25:37  09:25:37  mjames (Mike James)
  151.  * Added generics exported upwards
  152.  *
  153.  * Revision 1.11  98/10/01  15:25:30  15:25:30  mjames (Mike James)
  154.  * Added templates (name*) or * to set/del port
  155.  *
  156.  * Revision 1.10  98/04/24  13:49:07  13:49:07  mjames (Mike James)
  157.  * Added extra force_port flag to net for 'set port' command
  158.  *
  159.  * Revision 1.9  98/02/11  11:26:53  11:26:53  mjames (Mike James)
  160.  * Checked in for version 6.2a
  161.  *
  162.  * Revision 1.8  97/04/23  08:43:20  08:43:20  mjames (Mike James)
  163.  * CHecked in for release rel23041997
  164.  *
  165.  * Revision 1.7  96/12/23  15:15:51  15:15:51  mjames (Mike James)
  166.  * Altered because find_socket takes a reference
  167.  * to the head-of-list-pointer noth the pointer itself.
  168.  *
  169.  * Revision 1.6  96/07/19  14:38:47  14:38:47  mjames (Mike James)
  170.  * Update to give to PRL
  171.  *
  172.  * Revision 1.5  1996/05/23  10:32:26  mjames
  173.  * Altered BUFFER and OUT pin rules to decide whether a
  174.  * signal crosses a partition boundary.
  175.  *
  176.  * Revision 1.4  96/05/21  14:16:07  14:16:07  mjames (Mike James)
  177.  * Added the concept ogf buffered pins to get some Shoamra2
  178.  * partitions to work properly.
  179.  *
  180.  * Revision 1.3  96/04/26  16:01:55  16:01:55  mjames (Mike James)
  181.  * Altered inside/outside determination of signal directions
  182.  *
  183.  * Revision 1.2  96/04/15  14:19:31  14:19:31  mjames (Mike James)
  184.  * Checkin before datatype printing
  185.  *
  186.  * Revision 1.1  96/03/29  14:46:13  14:46:13  mjames (Mike James)
  187.  * Initial revision
  188.  *
  189.  *  */
  190. /* The Partition module. This combines VHDL for the purposes of creating
  191.    EPLDs */
  192.  
  193. #include "partition.h"
  194.  
  195. #include "acf_yacc.h"
  196. #include "chck_names.h"
  197. #include "cmdlog.h"
  198. #include "cmdparse.h"
  199. #include "database.h"
  200. #include "expression.h"
  201. #include "generic.h"
  202. #include "routing.h"
  203. #include "sorting.h"
  204. #include "vertcl_main.h"
  205. #include "vertcl_main.h"
  206.  
  207. #include <regex.h>
  208. #include <stdio.h>
  209. #include <stdlib.h>
  210. #include <string.h>
  211. #include <sys/types.h>
  212.  
  213. #ident                                                                                        \
  214.     "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/partition.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $"
  215.  
  216. /* nets created as a result of partition are ripped up when a new partition
  217.    is created */
  218.  
  219. void clear_partition_nets (void)
  220. {
  221.         net_t *net = named_list; /* only interested in nets carrying a signal */
  222.         while (net)
  223.         {
  224.                 net->leaves_partition = 0; /* not leaving partition */
  225.                 net->inside_partition = 0; /* not used inside partition */
  226.  
  227. #if defined BLOB
  228.                 if (!net->type_defined && net->vhdltype)
  229.                 {
  230.                         if (net->vhdltype->basetype)
  231.                         {
  232.                                 /* ought to free it */
  233.                                 free (net->vhdltype->basetype);
  234.                                 net->vhdltype->basetype = NULL;
  235.                         }
  236.                         if (net->vhdltype->expr)
  237.                         {
  238.                                 net->vhdltype = NULL;
  239.                                 free_expression (net->vhdltype->expr);
  240.                         }
  241.                 }
  242. #endif
  243.                 net = net->next;
  244.         }
  245. }
  246.  
  247. /* all nets that are in the routed list are named and placed in the named list */
  248.  
  249. void name_routed_nets (void)
  250. {
  251.         net_t *link;
  252.         net_t *net = routed_list; /* check each net in turn */
  253.                                   /* this code is here : shoould it be ? */
  254.         while (net)
  255.         {
  256.                 noderef_t *noderefs = net->nodes;
  257.                 link = net->next;
  258.                 if (IS_ROUTABLE (noderefs->net->how_routed))
  259.                 {
  260.                         if (ISNULLSTR (net->name))
  261.                                 net->name = net->identifier;
  262.                         while (noderefs)
  263.                         {
  264.                                 /*      noderefs->node->in_use = 1; */
  265.                                 noderefs->node->name = net->name;
  266.                                 noderefs = noderefs->next;
  267.                         }
  268.                         combine_routed_and_unrouted (net, net);
  269.                         transfer_net_to_named (&routed_list, net);
  270.                 }
  271.                 net = link;
  272.         }
  273. }
  274.  
  275. int set_clear_partition (char *expr, int set_clear)
  276. {
  277.         int rc;
  278.         socket_t *skt = socket_head;
  279.         int found = 0;
  280.         int process_count = 0;
  281.  
  282.         /* compile regular expression */
  283.         vert_regex_t *preg;
  284.  
  285.         rc = vert_regcomp (&preg, expr);
  286.  
  287.         if (rc != 0)
  288.         {
  289.                 char errbuff[100];
  290.                 regerror (rc, preg->preg, errbuff, 100);
  291.                 Log (
  292.                     LOG_ERROR,
  293.                     "-- Problem (rc=%d) %s with '%s' as regular expression\n",
  294.                     rc,
  295.                     errbuff,
  296.                     expr);
  297.  
  298.                 return /*TCL_ERROR*/;
  299.         }
  300.         else
  301.         {
  302.                 Log (LOG_GENERAL, "-- Using '%s' as match pattern\n", expr);
  303.         }
  304.  
  305.         while (skt)
  306.         {
  307.                 found = regexec (preg->preg, skt->identifier, 0, preg->regpatt, 0);
  308.                 if (!found)
  309.                 {
  310.                         if (skt && ISNULLSTR (skt->name))
  311.                         {
  312.                                 skt->name = skt->identifier;
  313.                         }
  314.                         skt->selected = set_clear;
  315.                         process_count++;
  316.                 }
  317.                 skt = skt->next;
  318.         }
  319.  
  320.         vert_regfree (&preg);
  321.         Log (LOG_GENERAL, "-- Processed %d sockets\n", process_count++);
  322.         return OKCMD;
  323. }
  324.  
  325. int add_all_to_partition (void)
  326. {
  327.         return set_clear_partition (".*", 1);
  328. }
  329.  
  330. /* printout the sockets that are selected inside the partition */
  331. void list_partition (FILE *f)
  332. {
  333.         socket_t *skt = socket_head;
  334.         fprintf (f, "Partition includes the following blocks:\n");
  335.         while (skt)
  336.         {
  337.                 if (skt->selected) /* selected */
  338.                         fprintf (f, "  '%s'\n", skt->name);
  339.                 skt = skt->next;
  340.         }
  341.         fprintf (f, "-- End list -- \n");
  342. }
  343.  
  344. /* the partitioning algorithm is implemented here */
  345. /*
  346.      for each net on the named list -- Made it to routing
  347.      if the only nodes on the list that are 'in use' only connect
  348.        to 'selected' sockets and there is an output or buffer pin inside the          then the
  349.    net is inside the partition. if the net is all inputs the the net has to leave the partition
  350.    as an input.
  351. */
  352. void perform_partition (void)
  353. {
  354.         net_t *net = named_list; /* check each net in turn */
  355.         int ports = 0;
  356.         int port_wires = 0;
  357.         int signals = 0;
  358.         int signal_wires = 0;
  359.  
  360.         while (net)
  361.         {
  362.                 noderef_t *noderefs = net->nodes;
  363.                 char used_outside = 0; /* set if the net goes outside */
  364.                 char used_inside = 0;  /* set if the net used inside */
  365.                 char inputs_on_net = 0;
  366.                 char outputs_on_net = 0;
  367.                 char buffers_on_net = 0; /* another pin type that we must handle */
  368.                 char bidirs_on_net = 0;
  369.                 char default_drive = 0; /* Was this net defined with a default value ? */
  370.  
  371.                 int width = 0; /* how many wires in the bundle */
  372.                 int high = 0;
  373.                 int low = 1000;
  374.  
  375.                 expression_t *exp, *variable_seen, *high_ref, *low_ref, *high_exp, *low_exp,
  376.                     *highest_exp, *lowest_exp;
  377.  
  378.                 highest_exp = NULL;
  379.                 lowest_exp = NULL;
  380.                 high_ref = NULL; /* reference to expression containing highest expr */
  381.                 low_ref = NULL;
  382.                 variable_seen = NULL;
  383.                 net->ext_dir = NONE; /* not yet known */
  384.  
  385.                 /* set flag if the net was defined as "signal x : type := value;" */
  386.                 default_drive =
  387.                     net->type_defined && net->vhdltype && net->vhdltype->default_expr;
  388.  
  389.                 /* predefined net type definition, can already know upper ansd lower bounds */
  390. #if defined DEBUG_EXPRESSION
  391.                 printf ("net %s \n", net->identifier);
  392. #endif
  393.                 while (noderefs)
  394.                 {
  395.                         node_t *n = noderefs->node;
  396.  
  397.                         if (n->in_use)
  398.                         {
  399.                                 int h, l;
  400.                                 vhdl_t *vhdl;
  401.                                 vhdl = noderefs->vhdltype;
  402.                                 if (vhdl && vhdl->expr)
  403.                                         exp = vhdl->expr;
  404.                                 else
  405.                                         exp = NULL;
  406.  
  407. #if defined DEBUG_EXPRESSION
  408.                                 if (exp)
  409.                                 {
  410.                                         printf ("expression vhdl%p expr%p", vhdl, exp);
  411.                                         print_range_expression (stdout, exp, 0);
  412.                                         printf ("\n");
  413.                                 }
  414. #endif
  415.                                 /* if we have a variable defining width,
  416.                                    remember what the top level variable is called,
  417.                                    then keep expanding it until we get an expression
  418.                                    rather than a variable */
  419.                                 if (exp && exp->opcode == EXP_VARIABLE)
  420.                                 {
  421.                                         variable_seen = exp;
  422.                                         while (exp->opcode == EXP_VARIABLE)
  423.                                                 exp = exp->left.g->expr;
  424.                                 }
  425.                                 if (exp)
  426.                                 {
  427.                                         if (exp->opcode == TO)
  428.                                         {
  429.                                                 high_exp = exp->right.e;
  430.                                                 low_exp = exp->left.e;
  431.                                         }
  432.                                         else if (exp->opcode == DOWNTO)
  433.                                         {
  434.                                                 high_exp = exp->left.e;
  435.                                                 low_exp = exp->right.e;
  436.                                         }
  437.                                         else
  438.                                                 high_exp = low_exp =
  439.                                                     exp; /* not a range, just a single value */
  440.  
  441.                                         l = eval_expression (low_exp, NULL);
  442.                                         h = eval_expression (high_exp, NULL);
  443.                                         /* sort out the highest and lowest bound of any logic
  444.                                            vector pins on the net (high and low are zero for
  445.                                            single bits so calculation applies here) */
  446.                                         if (h > high)
  447.                                         {
  448.                                                 highest_exp = high_exp;
  449.                                                 high_ref = exp;
  450.                                                 high = h;
  451.                                         }
  452.                                         if (l < low)
  453.                                         {
  454.                                                 lowest_exp = low_exp;
  455.                                                 low_ref = exp;
  456.                                                 low = l;
  457.                                         }
  458.                                 }
  459.                                 else
  460.                                 {
  461.                                         high = 0;
  462.                                         low = 0;
  463.                                 };
  464.  
  465.                                 /* discover it is routed outside - it links to an unselected
  466.                                  * socket */
  467.                                 /* but if it only links to unselected sockets,
  468.                                    used_inside wont be set as well */
  469.                                 if (!n->socket->selected)
  470.                                         used_outside = 1;
  471.                                 else
  472.                                 {
  473.                                         used_inside = 1;
  474.                                         if (noderefs->pindir == INPUT)
  475.                                                 inputs_on_net = 1;
  476.                                         if (noderefs->pindir == OUTPUT)
  477.                                                 outputs_on_net = 1;
  478.                                         if (noderefs->pindir == BIDIR)
  479.                                                 bidirs_on_net = 1;
  480.                                         if (noderefs->pindir == BUFFER)
  481.                                                 buffers_on_net = 1;
  482.  
  483.                                         /* I was  using the ordinal value of the pindir_t type
  484.                                       if  (noderefs->pindir >= net->ext_dir ) ||  */
  485.  
  486.                                         /* now June 1999 takes on the type of the first node ,
  487.                                           or if one of the nodes has a bus connection use that
  488.                                           : still a guess. Alternatively if the net was
  489.                                           declared so it has a type defined then keep that as
  490.                                           it is more correct...  */
  491.  
  492.                                         if (!net->type_defined &&
  493.                                             (!net->vhdltype || !net->vhdltype->basetype ||
  494.                                              (!net->vhdltype->is_vector && vhdl->is_vector)))
  495.                                         {
  496.                                                 /* copy over base VHDL type and vector/single
  497.                                                  * signal attribute*/
  498.  
  499.                                                 net->vhdltype = copy_vhdl (vhdl, NULL);
  500.                                         }
  501.                                 }
  502.                         }
  503.                         noderefs = noderefs->next;
  504.                 }
  505.  
  506. /* nets with a VHDL type will simply use this type as the definition of the expression */
  507. #if defined IGNORE_DEFINED
  508.                 if (net->type_defined && net->vhdltype)
  509.                 {
  510.                         exp = net->vhdltype->expr;
  511.                         if (exp && exp->opcode == EXP_VARIABLE)
  512.                                 exp = exp->left.g->expr;
  513.                         if (exp)
  514.                         {
  515.                                 if (exp->opcode == TO)
  516.                                 {
  517.                                         highest_exp = exp->right.e;
  518.                                         lowest_exp = exp->left.e;
  519.                                 }
  520.                                 else if (exp->opcode == DOWNTO)
  521.                                 {
  522.                                         highest_exp = exp->left.e;
  523.                                         lowest_exp = exp->right.e;
  524.                                 }
  525.                                 else
  526.                                         highest_exp = lowest_exp = exp->left.e;
  527.                                 low = eval_expression (lowest_exp, NULL);
  528.                                 high = eval_expression (highest_exp, NULL);
  529.                         }
  530.                 }
  531. #endif
  532.  
  533.                 if (!net->type_defined && net->vhdltype && net->vhdltype->is_vector)
  534.                 {
  535.                         if (variable_seen)
  536.                                 net->vhdltype->expr = variable_seen;
  537.  
  538.                         else if (highest_exp && lowest_exp)
  539.                         {
  540.                                 if (high_ref && (high_ref == low_ref))
  541.                                         net->vhdltype->expr = high_ref;
  542.                                 else
  543.                                         net->vhdltype->expr = compile_expression (
  544.                                             DOWNTO, highest_exp, lowest_exp);
  545.                         }
  546.                         else
  547.                                 net->vhdltype->expr = compile_constant (0);
  548.                 }
  549.  
  550.                 /* pin will appear on port list if : */
  551.                 /* routed inside & outside */
  552.                 net->leaves_partition =
  553.                     (used_inside && used_outside) ||
  554.                     /* inputs but not any sort of outputs, or default drive (a kind of output)
  555.                      */
  556.                     (inputs_on_net && !(default_drive || outputs_on_net || buffers_on_net)) ||
  557.                     /* any sort of outputs but not inputs */
  558.                     ((outputs_on_net || buffers_on_net) && !inputs_on_net) ||
  559.                     /* any bidirectional pins */
  560.                     bidirs_on_net ||
  561.                     /* net is forced as a port */
  562.                     net->force_port;
  563.  
  564.                 net->needs_buff_sig = inputs_on_net && (outputs_on_net || buffers_on_net) &&
  565.                                       net->leaves_partition;
  566.  
  567.                 /* sort out the pin directions */
  568.                 /* any bidirectional pins */
  569.                 if (bidirs_on_net)
  570.                         net->ext_dir = BIDIR;
  571.                 /* inputs but not any sort of outputs */
  572.                 else if (inputs_on_net && !(outputs_on_net || buffers_on_net))
  573.                         net->ext_dir = INPUT;
  574.                 /* any sort of outputs but not inputs */
  575.                 else if (outputs_on_net || buffers_on_net)
  576.                         net->ext_dir = OUTPUT;
  577.                 else
  578.                         net->ext_dir = NONE;
  579.                 /* net will appear in local signal definition if : */
  580.                 /* it is used inside  */
  581.                 /* and either only inside or it is a BUFFER
  582.                    port in which
  583.                    case a temporary signal is provided by
  584.                    printout.c */
  585.                 net->inside_partition =
  586.                     used_inside && ((!net->leaves_partition) || (net->needs_buff_sig));
  587.  
  588.                 width = high - low + 1;
  589.                 if (level & 1)
  590.                 {
  591.                         printf (
  592.                             "Partition : Net %-20s Inside %d Outside %d Crossing Dir %d width "
  593.                             "%d %c%c%c%c%c\n",
  594.                             net->name,
  595.                             net->inside_partition,
  596.                             net->leaves_partition,
  597.                             net->ext_dir,
  598.                             width,
  599.                             outputs_on_net ? 'O' : 'o',
  600.                             inputs_on_net ? 'I' : 'i',
  601.                             bidirs_on_net ? 'B' : 'b',
  602.                             buffers_on_net ? 'U' : 'u',
  603.                             default_drive ? 'D' : 'd');
  604.                 }
  605.  
  606.                 /* compute the bus width unless it is already defined  */
  607.  
  608.                 if (net->leaves_partition)
  609.                 {
  610.                         port_wires += width;
  611.                         ports++;
  612.                 };
  613.                 if (net->inside_partition)
  614.                 {
  615.                         signal_wires += width;
  616.                         signals++;
  617.                 };
  618.                 net = net->next;
  619.         }
  620.         Log (
  621.             LOG_GENERAL,
  622.             "-- %5d Nets    (%5d wires) leaving partition\n"
  623.             "-- %5d Signals (%5d wires) inside partition\n",
  624.             ports,
  625.             port_wires,
  626.             signals,
  627.             signal_wires);
  628. }
  629.  
  630. /* remove a port from the partition as I dont want it outside */
  631. void delete_port (char *template)
  632. {
  633.         int rc;
  634.         net_t *net = named_list;
  635.         int found = 0;
  636.         int net_count = 0;
  637.         /* compile regular expression */
  638.         vert_regex_t *preg;
  639.  
  640.         rc = vert_regcomp (&preg, template);
  641.  
  642.         if (rc != 0)
  643.         {
  644.                 char errbuff[100];
  645.                 regerror (rc, preg->preg, errbuff, 100);
  646.                 Log (
  647.                     LOG_ERROR,
  648.                     "-- Problem (rc=%d) %s with '%s' as regular expression\n",
  649.                     rc,
  650.                     errbuff,
  651.                     template);
  652.  
  653.                 return /*TCL_ERROR */;
  654.         }
  655.  
  656.         Log (LOG_GENERAL, "-- Beginning removing ports : prefix '%s' --\n", template);
  657.  
  658.         while (net)
  659.         {
  660.                 found = regexec (preg->preg, net->name, 0, preg->regpatt, 0);
  661.                 if (found && found != REG_NOMATCH)
  662.                 {
  663.                         char errbuff[100];
  664.                         regerror (found, preg->preg, errbuff, 100);
  665.                         Log (
  666.                             LOG_ERROR,
  667.                             "-- Problem (rc=%d) %s with '%s' as regular expression\n",
  668.                             found,
  669.                             errbuff,
  670.                             template);
  671.                 }
  672.  
  673.                 if (level & 1)
  674.                 {
  675.                         Log (LOG_GENERAL, "-- Net '%s'%s", net->name, found ? "\n" : "");
  676.                 }
  677.  
  678.                 if (!found)
  679.                 {
  680.                         if (level & 1)
  681.                         {
  682.                                 Log (
  683.                                     LOG_GENERAL,
  684.                                     "inside=%d leaves=%d buffer=%d force_port=%d\n",
  685.                                     net->inside_partition,
  686.                                     net->leaves_partition,
  687.                                     net->needs_buff_sig,
  688.                                     net->force_port);
  689.                         }
  690.  
  691.                         net->force_port = 0;
  692.                         /* now to delete the port the following is needed to be done */
  693.                         /* Is it going outside ? If not , forget it */
  694.                         /* otherwise ensure its used inside, not a port and its not needing a
  695.                          * buffer */
  696.  
  697.                         if (net->leaves_partition || net->needs_buff_sig)
  698.                         {
  699.                                 net->leaves_partition = 0;
  700.                                 net->inside_partition = 1;
  701.                                 net->needs_buff_sig = 0;
  702.                                 if (level & 1)
  703.                                         Log (
  704.                                             LOG_GENERAL,
  705.                                             "-- Removed port '%s' from partion\n",
  706.                                             net->name);
  707.                                 net_count++;
  708.                         }
  709.                 }
  710.                 net = net->next;
  711.         }
  712.  
  713.         Log (LOG_GENERAL, "-- Removed %d ports from partiton\n", net_count);
  714.         Log (LOG_GENERAL, "-- Done removing ports \n");
  715.         vert_regfree (&preg);
  716. }
  717.  
  718. /* force a net to be a port on the partition as I want it outside */
  719. void force_port (char *template)
  720. {
  721.         int rc;
  722.         net_t *net = named_list;
  723.         int found;
  724.         int net_count = 0;
  725.         /* compile regular expression */
  726.         vert_regex_t *preg;
  727.  
  728.         rc = vert_regcomp (&preg, template);
  729.  
  730.         if (rc != 0)
  731.         {
  732.                 char errbuff[100];
  733.                 regerror (rc, preg->preg, errbuff, 100);
  734.                 Log (
  735.                     LOG_ERROR,
  736.                     "-- Problem (rc=%d) %s with '%s' as regular expression\n",
  737.                     rc,
  738.                     errbuff,
  739.                     template);
  740.  
  741.                 return /*TCL_ERROR */;
  742.         }
  743.  
  744.         Log (LOG_GENERAL, "-- Beginning setting ports : prefix '%s' --\n", template);
  745.  
  746.         while (net)
  747.         {
  748.                 found = regexec (preg->preg, net->name, 0, preg->regpatt, 0);
  749.  
  750.                 if (!found)
  751.                 {
  752.                         if (level & 1)
  753.                                 Log (
  754.                                     LOG_GENERAL,
  755.                                     "-- Set '%s' as a port if it is inside partition\n",
  756.                                     net->name);
  757.                         net->force_port = 1;
  758.                         net_count++;
  759.                 }
  760.                 net = net->next;
  761.         }
  762.         Log (LOG_GENERAL, "-- Forced %d ports on partion\n", net_count);
  763.         Log (LOG_GENERAL, "-- Port forcing done\n");
  764.         vert_regfree (&preg);
  765. }
  766.