Subversion Repositories Vertical

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* contains the database functions that store the pin configurations
  2.  *
  3.  * $Header: c:\\cygwin\\cvsroot/Vert03/vertlib/database.c,v 1.1.1.1 2003/11/04 23:34:57 mjames
  4.  * Exp $ $Log: database.c,v $ Revision 1.1.1.1  2003/11/04 23:34:57  mjames Imported into local
  5.  * repositrory
  6.  *
  7.  * Revision 1.13  2003/01/02 21:37:15  mjames
  8.  * Experiment on creating NOT_ROUTABLE_H and NOT_ROUTABLE_L
  9.  * properties on the nets so that pin jumpers can be made without a problem.
  10.  *
  11.  * Still need to sort out pin assignments made to these not_routable nets
  12.  * which will become legal in some cases so that pullups and pulldown
  13.  * pins can be used on the FPGA.
  14.  *
  15.  * Revision 1.12  2002/09/30 13:26:49  MJAMES
  16.  * Upgraded nets to include 'lhs_expression' being the range on the
  17.  * left hand side of a signal connection to a port
  18.  *
  19.  * std_logic_vector (0) <= std_logic , on a port of a chip
  20.  *
  21.  * Revision 1.11  2002/08/06 12:52:54  mjames
  22.  * Merge in from latest version
  23.  *
  24.  *
  25.  * Revision 1.11  2002/03/21 17:13:05  mjames
  26.  * Added search path to vertical file opening for read
  27.  *
  28.  * Revision 1.10  2002/01/15 12:32:42  mjames
  29.  * DLL declarations put in,
  30.  *
  31.  * #ident used
  32.  *
  33.  * Revision 1.9  2001/11/19 09:45:25  mjames
  34.  * Corrected some case statments with no default action
  35.  *
  36.  * Revision 1.8  2001/10/31 22:20:02  mjames
  37.  * Tidying up problematical comments caused by CVS
  38.  * 'intelligent' comment guessing
  39.  *
  40.  * Revision 1.7  2001/10/31 16:22:55  mjames
  41.  * Added a datastructure to hide regular expression information from programs.
  42.  * Changed call to regexec to indicate 0 subexpressions to be matched
  43.  * rather than a number dependent on strlen(string) which was wrong.
  44.  * Net disconnection works on routed and named nets
  45.  *
  46.  * Revision 1.6  2001/10/23 21:12:43  mjames
  47.  * Created preliminary 'disconnect_node' function
  48.  *
  49.  * Revision 1.5  2001/10/10 20:18:24  mjames
  50.  * Added a vert_regcomp function to compile regular expressions
  51.  * with '^' (match start string) and  '$' (match end string) bracketing
  52.  * this => wildcard must match entire string not just a part of it.
  53.  *
  54.  * Revision 1.4  2001/10/07 20:50:53  mjames
  55.  * Added wildcard checking (warn user about
  56.  * using wildcard '*' on the end of a string in stead of wildcard '.*')
  57.  *
  58.  * Revision 1.3  2001/09/25 23:15:24  mjames
  59.  * Converted wildcards to use proper regexp pattern match library
  60.  *
  61.  * Revision 1.2  2001/06/06 12:10:24  mjames
  62.  * Move from HPUX
  63.  *
  64.  * Revision 1.1.1.1  2000/10/19 21:58:35  mjames
  65.  * Mike put it here
  66.  *
  67.  *
  68.  * Revision 1.61  2000/10/04  10:37:03  10:37:03  mjames (Mike James)
  69.  * COnversion to Vertical2, supports signals and components
  70.  *
  71.  * Revision 1.61  2000/10/04  10:37:03  10:37:03  mjames (Mike James)
  72.  * Part of Release PSAVAT01
  73.  *
  74.  * Revision 1.60  2000/10/03  10:05:27  10:05:27  mjames (Mike James)
  75.  * Added CONSTANTS and SIGNALS to architecture
  76.  *
  77.  * Revision 1.58  2000/09/27  14:42:11  14:42:11  mjames (Mike James)
  78.  * Part of Release Sep_27_ST_2000
  79.  *
  80.  * Revision 1.57  2000/09/21  10:15:40  10:15:40  mjames (Mike James)
  81.  * Part of Release Sep21Alpha
  82.  *
  83.  * Revision 1.56  2000/09/21  09:44:29  09:44:29  mjames (Mike James)
  84.  * Added in code to deal with pin equivalents, and removed some
  85.  * spurious diagnostic puts() calls .
  86.  *
  87.  * Revision 1.55  2000/08/25  09:57:09  09:57:09  mjames (Mike James)
  88.  * Part of Release Aug25_alpha
  89.  *
  90.  * Revision 1.54  2000/08/16  08:57:26  08:57:26  mjames (Mike James)
  91.  * Part of Release CD01_Aug2000
  92.  *
  93.  * Revision 1.53  2000/08/14  14:45:07  14:45:07  mjames (Mike James)
  94.  * Part of Release Aug_14_2000
  95.  *
  96.  * Revision 1.52  2000/08/11  08:30:28  08:30:28  mjames (Mike James)
  97.  * Part of Release Aug_11_2000
  98.  *
  99.  * Revision 1.51  2000/08/09  10:31:41  10:31:41  mjames (Mike James)
  100.  * Part of Release Aug__9_2000
  101.  *
  102.  * Revision 1.50  2000/05/31  11:42:48  11:42:48  mjames (Mike James)
  103.  * Part of Release May_31_2000
  104.  *
  105.  * Revision 1.49  2000/05/08  17:01:33  17:01:33  mjames (Mike James)
  106.  * Part of Release May__8_2000
  107.  *
  108.  * Revision 1.48  2000/05/08  16:59:26  16:59:26  mjames (Mike James)
  109.  * Part of Release May__8_2000
  110.  *
  111.  * Revision 1.47  2000/05/08  16:57:03  16:57:03  mjames (Mike James)
  112.  * Part of Release May__8_2000
  113.  *
  114.  * Revision 1.46  2000/03/08  16:18:48  16:18:48  mjames (Mike James)
  115.  * New version including PC
  116.  *
  117.  * Revision 1.43  2000/02/18  15:45:24  15:45:24  mjames (Mike James)
  118.  * Amended to support PC
  119.  *
  120.  * Revision 1.42  2000/01/20  15:58:41  15:58:41  mjames (Mike James)
  121.  * Part of Release R22
  122.  *
  123.  * Revision 1.41  99/12/22  11:15:22  11:15:22  mjames (Mike James)
  124.  * Part of Release Dec_22_1999
  125.  *
  126.  * Revision 1.40  99/06/25  14:34:42  14:34:42  mjames (Mike James)
  127.  * Added in reference to expression.h, but no changes made
  128.  * to the function of acfread yet.
  129.  *
  130.  * Revision 1.39  99/06/18  09:23:19  09:23:19  mjames (Mike James)
  131.  *
  132.  * Revision 1.38  99/05/04  09:50:36  09:50:36  mjames (Mike James)
  133.  * General checkin
  134.  *
  135.  * Revision 1.34  98/08/12  14:19:52  14:19:52  mjames (Mike James)
  136.  * Changed pin definition code to work with VHDL
  137.  * parsing
  138.  * as well as include file list being updated
  139.  *
  140.  * Revision 1.33  98/06/15  14:17:51  14:17:51  mjames (Mike James)
  141.  * Added socket templating pointers - reference to parent template
  142.  * for child template.
  143.  *
  144.  * Revision 1.32  98/02/11  11:25:52  11:25:52  mjames (Mike James)
  145.  * Checked in for version 6.2a
  146.  *
  147.  * Revision 1.31  98/01/13  11:33:35  11:33:35  mjames (Mike James)
  148.  * Added the bility to use a VHDL template file
  149.  * containing $ENT$ and $ARCH$ in the position where one
  150.  * wants the entity and architecture to be given.
  151.  *
  152.  * Revision 1.30  97/04/23  08:42:49  08:42:49  mjames (Mike James)
  153.  * CHecked in for release rel23041997
  154.  *
  155.  * Revision 1.29  96/12/23  15:13:48  15:13:48  mjames (Mike James)
  156.  * Added reverse pointer to show which unrouted net was
  157.  * responsible for the fixing of the pins.
  158.  *
  159.  * Revision 1.28  96/12/23  10:24:02  10:24:02  mjames (Mike James)
  160.  * Altered to make it sort the results
  161.  * of listing COMPONENTS and CHIP pins.
  162.  * /
  163.  *
  164.  * Revision 1.27  96/12/13  08:43:08  08:43:08  mjames (Mike James)
  165.  * Update to v5.1, added Write ID , exact routing
  166.  *
  167.  * Revision 1.26  96/08/06  13:38:51  13:38:51  mjames (Mike James)
  168.  * Added FIX_LOCATION pin attribute to netlist
  169.  *
  170.  * Revision 1.25  96/07/19  14:38:43  14:38:43  mjames (Mike James)
  171.  * Update to give to PRL
  172.  *
  173.  * Revision 1.24  1996/07/12  15:52:12  mjames
  174.  * Sorted out things like Alias and Jumpers
  175.  * Work Correctly
  176.  * Print COrrectly
  177.  *
  178.  * Revision 1.23  96/07/09  15:53:59  15:53:59  mjames (Mike James)
  179.  * Altered aliasing to make it hierarchical, also for jumpering
  180.  *
  181.  * Revision 1.22  96/06/17  11:02:43  11:02:43  mjames (Mike James)
  182.  * Altered the printing of JUMPERED and ALIASED nets
  183.  * ,
  184.  *
  185.  * Revision 1.21  96/06/11  14:11:44  14:11:44  mjames (Mike James)
  186.  * Added hierarchical jumpering
  187.  *
  188.  * Revision 1.20  96/06/04  11:53:18  11:53:18  mjames (Mike James)
  189.  * Added the ability to jumper nets by reference to a node on the nets
  190.  *
  191.  * Revision 1.19  96/05/29  10:52:29  10:52:29  mjames (Mike James)
  192.  *  Added name suffixing to socket ID's and net ID's
  193.  *
  194.  * Revision 1.18  96/04/26  16:01:30  16:01:30  mjames (Mike James)
  195.  * Added SET PORT to force ports on partition
  196.  * ,
  197.  *
  198.  * Revision 1.17  96/04/15  14:19:24  14:19:24  mjames (Mike James)
  199.  * Checkin before datatype printing
  200.  * modifications
  201.  *
  202.  * Revision 1.16  96/03/29  14:46:05  14:46:05  mjames (Mike James)
  203.  * Added VHDL netlist writing to the capabilities of ACFREAD
  204.  *
  205.  * Revision 1.14  96/03/18  13:50:28  13:50:28  mjames (Mike James)
  206.  * Real Revision 2.1
  207.  *
  208.  * Revision 1.11  96/03/13  15:35:30  15:35:30  mjames (Mike James)
  209.  * Changed the name_pref filed to reflect how a net has been routed
  210.  *
  211.  * Revision 1.10  96/02/13  09:13:28  09:13:28  mjames (Mike James)
  212.  * Updated to be version 2.0 with net joining
  213.  *
  214.  * Revision 1.9  96/02/09  10:50:24  10:50:24  mjames (Mike James)
  215.  * Added different behaviour for 'write id' and 'write name'
  216.  * 'write id' now writes all pins including unused ones
  217.  * 'write name' only writes used pins in the ACF file
  218.  *
  219.  *  .
  220.  *
  221.  *
  222.  * Revision 1.8  96/02/08  15:28:29  15:28:29  mjames (Mike James)
  223.  * First release
  224.  *
  225.  * Revision 1.7  96/02/07  16:01:34  16:01:34  mjames (Mike James)
  226.  * Added correct RCS header
  227.  *
  228.  * Revision 1.6  96/02/07  15:50:44  15:50:44  mjames (Mike James)
  229.  * Added RCS ident message
  230.  *
  231.  * Revision 1.5  96/02/07  11:04:07  11:04:07  mjames (Mike James)
  232.  * Checkin before adding new command parsing to program
  233.  *
  234.  * Revision 1.4  96/01/10  13:14:11  13:14:11  mjames (Mike James)
  235.  *  Works in debug mode with EPLD listings and PCB layout
  236.  *
  237.  * Revision 1.3  96/01/08  15:22:51  15:22:51  mjames (Mike James)
  238.  * Managing to make sense of things now
  239.  *
  240.  * Revision 1.2  96/01/07  20:22:29  Mike_James
  241.  * extending database routines
  242.  *
  243.  * Revision 1.1  96/01/07  12:38:12  Mike_James
  244.  * Initial revision
  245.  *
  246.  * Revision 1.2  96/01/04  17:55:52  17:55:52  mjames (Mike James)
  247.  * Correcly reading ACF
  248.  *
  249.  * Revision 1.1  96/01/04  11:37:22  11:37:22  mjames (Mike James)
  250.  * Initial revision
  251.  *
  252.  */
  253. #include "database.h"
  254.  
  255. #include "acf_yacc.h"
  256. #include "chck_names.h"
  257. #include "cmdlog.h"
  258. #include "cmdparse.h"
  259. #include "expression.h"
  260. #include "generic.h"
  261. #include "lx_support.h"
  262. #include "sorting.h"
  263. #include "version.h"
  264. #include "vertcl_main.h"
  265.  
  266. #include <ctype.h>
  267. #include <regex.h>
  268. #include <stdio.h>
  269. #include <stdlib.h>
  270. #include <string.h>
  271. #include <sys/types.h>
  272.  
  273. #ident                                                                                        \
  274.     "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/database.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $"
  275.  
  276. vhdl_t *default_vhdl_datatype;
  277. vhdl_t *default_vhdl_bustype;
  278.  
  279. /* string constants used around the place*/
  280.  
  281. char nullstr[] = "";
  282.  
  283. /* database pointers */
  284. __declspec(dllexport) socket_t *socket_head = NULL;
  285.  
  286. __declspec(dllexport) socket_t *template_head = NULL;
  287.  
  288. net_t *routed_list = NULL;
  289. net_t *named_list = NULL;
  290. net_t *named_tail = NULL; /* as routed nets are moved to the named list */
  291. net_t *unrouted_list = NULL;
  292.  
  293. /* these are ident counters. The first counts net identifiers */
  294. static int n_idents = 1; /* net identifiers */
  295. static int s_idents = 1; /* socket identifiers */
  296. static int i_idents = 1; /* pin identifiers */
  297.  
  298. /* compares two strings case insensitive with a pointer sanity check */
  299.  
  300. int strcmp2 (char *s, char *t)
  301. {
  302.         if (!s || !t)
  303.                 return (-1);
  304.         for (; tolower (*s) == tolower (*t); s++, t++)
  305.                 if (*s == 0)
  306.                         return (0);
  307.         return (tolower (*s) - tolower (*t));
  308. }
  309.  
  310. /* allocates a space for a string */
  311.  
  312. #if !defined allocstr
  313. /* we now use strdup.... */
  314. char *allocstr (char *s)
  315. {
  316.         char *t;
  317.         /* added a check for allocating null string
  318.          *  (its strlen that bombs in CygWin) */
  319.         if (!s)
  320.                 return NULL;
  321.  
  322.         t = malloc (strlen (s) + 1);
  323.         strcpy (t, s);
  324.         return t;
  325. }
  326. #endif
  327.  
  328. /* allocates a space for a string and a suffix dependent on property */
  329.  
  330. #if defined USE_ALLOCSTR_PROP
  331. static char *allocstr_prop (char *s, property_t prop)
  332. {
  333.         char *t;
  334.         switch (prop)
  335.         {
  336.         case Ident:
  337.         case Type:
  338.         case Name:
  339.         case Value:
  340.                 t = strdup (s);
  341.                 break;
  342.         }
  343.         return t;
  344. }
  345. #endif
  346.  
  347. /* this is a check on a socket ident - if absent, generates one  */
  348.  
  349. __declspec(dllexport) void ensure_socket_ident (socket_t *chip)
  350. {
  351.         char id[10];
  352.         if (chip->identifier == nullstr)
  353.         {
  354.                 sprintf (id, "ID%d", s_idents++);
  355.                 set_socket (chip, Ident, id);
  356.         };
  357. }
  358.  
  359. /* set a socket property */
  360. __declspec(dllexport) void set_socket (socket_t *chip, property_t prop, char *str)
  361. {
  362.         char *s;
  363.         s = strdup (str);
  364.  
  365.         /*   printf("(Set socket prop%d to %s)",prop,s); */
  366.         switch (prop)
  367.         {
  368.         case Ident:
  369.                 chip->identifier = s;
  370.                 break;
  371.         case Type:
  372.                 chip->type = s;
  373.                 break;
  374.         case Name:
  375.                 chip->name = s;
  376.                 break;
  377.         case Value:
  378.                 chip->value = s;
  379.                 break;
  380.         default:
  381.                 break;
  382.         };
  383. }
  384.  
  385. /* find a socket property */
  386. __declspec(dllexport) socket_t *find_socket (
  387.     property_t prop, char *str, int srchonly, socket_t **headref)
  388. {
  389.         socket_t *c = *headref, *p = NULL;
  390.         int f = 0;
  391.         /* printf("-- Socket %s : prop %d pointer=%p\n",str,prop,c); */
  392.  
  393.         while (c)
  394.         {
  395.                 switch (prop)
  396.                 {
  397.                 case Ident:
  398.                         f = strcmp2 (c->identifier, str) == 0; /*puts(c->identifier); */
  399.                         break;
  400.                 case Type:
  401.                         f = strcmp2 (c->type, str) == 0;
  402.                         break;
  403.                 case Name:
  404.                         f = strcmp2 (c->name, str) == 0; /*puts(c->name);*/
  405.                         break;
  406.                 case Value:
  407.                         f = strcmp2 (c->value, str) == 0;
  408.                         break;
  409.                 default:
  410.                         break; /* never find if wrong field specified */
  411.                 };
  412.                 if (f)
  413.                         break;
  414.                 p = c;
  415.                 c = c->next;
  416.         };
  417.  
  418.         if (srchonly || f)
  419.                 return (c);
  420.  
  421.         c = calloc (1, sizeof (socket_t)); /* all pointers are set to be null */
  422.  
  423.         c->identifier = nullstr;
  424.         c->type = nullstr;
  425.         c->name = nullstr;
  426.         c->value = nullstr;
  427.  
  428.         set_socket (c, prop, allocstr (str));
  429.  
  430.         /* link in otherwise */
  431.         if (p)
  432.                 p->next = c;
  433.         if (!(*headref))
  434.                 *headref = c;
  435.         return c;
  436. }
  437.  
  438. /* matches s into a table of n strings r[], default value is d */
  439. int str_to_int (char *s, char *r[], int n, int d)
  440. {
  441.         int i;
  442.         for (i = 0; i < n; i++)
  443.                 if (strcmp2 (s, r[i]) == 0)
  444.                 {
  445.                         d = i;
  446.                         break;
  447.                 };
  448.         return d;
  449. }
  450.  
  451. char *decode_how_routed[] = {"FREE_NAME",
  452.                              "MATCHED_NAME",
  453.                              "USED_WIRES",
  454.                              "USED_FIXED_WIRES",
  455.                              "USED_EXACT_WIRES",
  456.                              "CREATED_NET",
  457.                              "CREATED_JUMPER",
  458.                              "FIXED_PINS",
  459.                              "NOT_ROUTABLE",
  460.                              "NOT_ROUTABLE_L", /* additions V16.5 onward */
  461.                              "NOT_ROUTABLE_H"};
  462.  
  463. /* set a net property */
  464. __declspec(dllexport) void set_net (net_t *net, property_t prop, char *str)
  465. {
  466.         char *s;
  467.         s = strdup (str);
  468.         switch (prop)
  469.         {
  470.         case Ident:
  471.                 net->identifier = s;
  472.                 break;
  473.         case Name:
  474.                 net->name = s;
  475.                 break;
  476.                 /*
  477.                     case Datatype:  net->datatype   = s; break;
  478.                 */
  479.         case How_Routed:
  480.                 net->how_routed = (HowRouted_t) str_to_int (
  481.                     str, decode_how_routed, sizeof (decode_how_routed) / sizeof (char *), 0);
  482.                 break;
  483.         default:
  484.                 break;
  485.         };
  486. }
  487.  
  488. /* find a net by property, in a list pointed to by a pointer referred to
  489.    by net_head  */
  490. __declspec(dllexport) net_t *find_net (
  491.     net_t **net_head, property_t prop, char *str, int srchonly)
  492. {
  493.         net_t *c, *p;
  494.         int f = 0;
  495.         c = *net_head;
  496.         p = NULL;
  497.         while (c)
  498.         {
  499.                 switch (prop)
  500.                 {
  501.                 case Ident:
  502.                         f = strcmp2 (c->identifier, str) == 0;
  503.                         break;
  504.                 case Name:
  505.                         f = strcmp2 (c->name, str) == 0;
  506.                         break;
  507.                 default:
  508.                         break;
  509.                 };
  510.                 if (f)
  511.                         break;
  512.                 p = c;
  513.                 c = c->next;
  514.         };
  515.         if (srchonly || f)
  516.                 return (c);
  517.  
  518.         c = calloc (1, sizeof (net_t)); /* all pointers are set to be null */
  519.         c->name = nullstr;
  520.         c->identifier = nullstr;
  521.         c->list_ref = net_head; /* record which list this net is a member of */
  522.  
  523.         c->nodecount = 0; /* calloc does this :  put here for readability : Oct 2000 */
  524.  
  525.         c->type_defined = 0;
  526.         set_net (c, prop, str);
  527.  
  528.         c->list_ref = net_head; /* which list does this net begin life on */
  529.  
  530.         /* link at end of list otherwise */
  531.         if (p)
  532.                 p->next = c;
  533.         c->prev = p; /* and refer back to it */
  534.         if (!(*net_head))
  535.                 *net_head = c;
  536.  
  537.         return c;
  538. }
  539.  
  540. /* set a node property */
  541. __declspec(dllexport) void set_node (node_t *node, property_t prop, char *str)
  542. {
  543.         char *s;
  544.         s = strdup (str);
  545.         switch (prop)
  546.         {
  547.         case Ident:
  548.                 node->identifier = s;
  549.                 break;
  550.         case Name:
  551.                 node->name = s;
  552.                 break;
  553.                 /*
  554.                     case Datatype:  node->datatype    = s; break;
  555.                 */
  556.         default:
  557.                 break;
  558.         };
  559. }
  560.  
  561. /* locate a node on a chip by a property */
  562. __declspec(dllexport) node_t *find_node (
  563.     socket_t *socket, property_t prop, char *str, int srchonly)
  564. {
  565.         node_t *c, *p;
  566.         int f = 0;
  567.  
  568.         /* catch null pointer reference 23 May 2001 */
  569.         if (!socket)
  570.                 return NULL;
  571.  
  572.         c = socket->nodes;
  573.  
  574.         p = NULL;
  575.         while (c)
  576.         {
  577.                 switch (prop)
  578.                 {
  579.                 case Ident:
  580.                         f = strcmp2 (c->identifier, str) == 0;
  581.                         break;
  582.                 case Name:
  583.                         f = strcmp2 (c->name, str) == 0;
  584.                         break;
  585.                         /*      case Datatype:  f=strcmp2(c->datatype,str)==0;       break; */
  586.                 default:
  587.                         break;
  588.                 };
  589.                 if (f)
  590.                         break;
  591.                 p = c;
  592.                 c = c->sktnext;
  593.         };
  594.         if (srchonly || f)
  595.                 return (c);
  596.  
  597.         c = calloc (1, sizeof (node_t)); /* all pointers are set to be null */
  598.         c->name = nullstr;
  599.         c->identifier = nullstr;
  600.         c->socket = socket;
  601.  
  602.         set_node (c, prop, str);
  603.         /* link at end of list otherwise */
  604.         if (p)
  605.                 p->sktnext = c;
  606.  
  607.         if (!socket->nodes)
  608.                 socket->nodes = c;
  609.  
  610.         socket->lastnode = c;
  611.         return c;
  612. }
  613.  
  614. /* this connects the node to the list of node references on the net and
  615.    connects the net to the list of net references on the node */
  616.  
  617. __declspec(dllexport) void connect_node_net (
  618.     char *orig_name,
  619.     node_t *cnode,
  620.     net_t *cnet,
  621.     pindir_t pintype,
  622.     vhdl_t *vhdl,
  623.     vhdl_t *orig_vhdl,
  624.     expression_t *lhs_expr)
  625. {
  626.         noderef_t *noderef;
  627.         cnet->nodecount++; /* one more node on this net */
  628.  
  629.         cnode->net = cnet; /* refer back to net this node is on */
  630.         cnode->refcount++; /* and count references */
  631.  
  632.         noderef = calloc (1, sizeof (noderef_t));
  633.  
  634.         noderef->net = cnet; /* this node reference refers back to its parent net */
  635.  
  636.         noderef->pindir = pintype; /* the reference has the pin direction _wanted_ */
  637.  
  638.         noderef->orig_name = orig_name; /* copy any alias over */
  639.  
  640.         /* remeved reference to datatype */
  641.         noderef->vhdltype = vhdl;
  642.  
  643.         noderef->orig_vhdltype = orig_vhdl;
  644.  
  645.         noderef->base_noderef = noderef; /* its original reference is itself */
  646.  
  647.         noderef->lhs_expr = lhs_expr;
  648.  
  649.         /* link node  reference to the net */
  650.         noderef->next = cnet->nodes;
  651.         cnet->nodes = noderef; /* place reference on head of list */
  652.         noderef->node = cnode;
  653. }
  654.  
  655. /* disconnect a node from the netlist */
  656. /* this intends to remove chip node from net in the routed list. If anyone has made a reference
  657.    to the node in a manner which results in this node reappearing then there will be a problem
  658.    as it will reappear (some route algorithms eg. create will do this) */
  659.  
  660. __declspec(dllexport) void disconnect_node (socket_t *chip, node_t *node)
  661. {
  662.         noderef_t *ref, *last_ref;
  663.         /* locate the net on the routed or named list */
  664.         if (node->net &&
  665.             (node->net->list_ref == &routed_list || node->net->list_ref == &named_list))
  666.         {
  667.                 net_t *net;
  668.                 net = node->net;
  669.                 ref = net->nodes;
  670.                 last_ref = NULL;
  671.                 /* locate the reference made */
  672.                 while (ref)
  673.                 {
  674.                         if (ref->node == node)
  675.                                 break;
  676.                         last_ref = ref;
  677.                         ref = ref->next;
  678.                 }
  679.                 /* reference is located. Remove from list of node references,
  680.                    also patch up list head if needed */
  681.                 if (ref)
  682.                 {
  683.                         if (last_ref == NULL)
  684.                         {
  685.                                 net->nodes = ref->next;
  686.                         }
  687.                         else
  688.                         {
  689.                                 last_ref->next = ref->next;
  690.                         }
  691.                         free (ref);
  692.                         node->net = NULL; /* disconnect the ned from the node */
  693.                         node->refcount = node->refcount ? node->refcount-- : 0;
  694.                 }
  695.         }
  696. }
  697.  
  698. __declspec(dllexport) void define_pin (
  699.     net_t **net_head,
  700.     socket_t *chip,
  701.     char *i_name,
  702.     int pin_type,
  703.     int pin_group,
  704.     char *i_identifier,
  705.     vhdl_t *vhdl,
  706.     expression_t *lhs_expr)
  707. {
  708.         unrouted_ref_t *ref, *ptr;
  709.  
  710.         int null_name;
  711.         char name[MAXIDLEN];
  712.         char identifier[MAXIDLEN];
  713.  
  714.         /* actions here are :
  715.         1: find a new node;
  716.         2: attach a reference to it to the socket pin list;
  717.         3: find the net it is joined to by name;
  718.         */
  719.  
  720.         null_name = ISNULLSTR (i_name);
  721.  
  722.         /* if the name is not given, then dont create a net for it as it
  723.            is a waste of time */
  724.         if (null_name)
  725.                 /* count another ident for posisble use */
  726.                 sprintf (name, "NE%d", n_idents++);
  727.         else
  728.                 strcpy (name, i_name);
  729.  
  730.         if (ISNULLSTR (i_identifier))
  731.                 /* count another ident for posisble use */
  732.                 sprintf (identifier, "ID%d", i_idents++);
  733.         else
  734.                 strcpy (identifier, i_identifier);
  735.  
  736.         /*   printf("-- Joining name %s to pin %s\n",name,identifier );
  737.          */
  738.  
  739.         /* at this stage, simply create a potential reference */
  740.  
  741.         ref = calloc (1, sizeof (unrouted_ref_t));
  742.  
  743.         ref->pindir = pin_type; /* the reference has the pin direction _wanted_ */
  744.         ref->pin_group = pin_group;
  745.         /* removed reference to datatype */
  746.  
  747.         ref->vhdltype = copy_vhdl (vhdl, chip);
  748.         ref->orig_vhdltype = NULL;
  749.         ref->identifier = allocstr (identifier);
  750.         ref->name = allocstr (name);
  751.         ref->orig_name = NULL;
  752.         ref->listref = net_head; /* identify the list context */
  753.         ref->lhs_expr = lhs_expr;
  754.         ref->next = NULL;
  755.         if (!chip->unrouted_refs)
  756.                 chip->unrouted_refs = ref;
  757.         else
  758.         {
  759.                 ptr = chip->unrouted_refs;
  760.                 while (ptr->next)
  761.                         ptr = ptr->next;
  762.                 ptr->next = ref;
  763.         }
  764.  
  765.         /* splice the unrouted reference on */
  766.         ref->next = NULL;
  767. }
  768.  
  769. /* this function clears the name fields on identified nets */
  770. static void del_list_net_names (net_t *list, char *template)
  771. {
  772.         int rc, found;
  773.         char *pattern;
  774.         /* compile regular expression */
  775.         vert_regex_t *preg;
  776.  
  777.         if (template)
  778.         {
  779.                 pattern = template;
  780.         }
  781.         else
  782.         {
  783.                 pattern = ".*";
  784.         }
  785.  
  786.         rc = vert_regcomp (&preg, pattern);
  787.  
  788.         if (rc != 0)
  789.         {
  790.                 char errbuff[100];
  791.                 regerror (rc, preg->preg, errbuff, 100);
  792.                 Log (
  793.                     LOG_ERROR,
  794.                     "-- Problem (rc=%d) %s with '%s' as regular expression\n",
  795.                     rc,
  796.                     errbuff,
  797.                     pattern);
  798.  
  799.                 return /*TCL_ERROR*/;
  800.         }
  801.  
  802.         Log (
  803.             LOG_GENERAL,
  804.             "-- Beginning clearing name fields : net ID prefix '%s' --\n",
  805.             template ? template : "[ALL ID's]");
  806.         while (list)
  807.         {
  808.                 found = regexec (preg->preg, list->identifier, 0, preg->regpatt, 0);
  809.                 if (!found)
  810.                 {
  811.                         Log (
  812.                             LOG_GENERAL,
  813.                             "-- Cleared name field for net ID '%s'\n",
  814.                             list->identifier);
  815.                         list->name = nullstr;
  816.                 }
  817.                 list = list->next;
  818.         }
  819.         Log (LOG_GENERAL, "-- Finished clearing name fields --\n");
  820.         vert_regfree (&preg);
  821. }
  822.  
  823. __declspec(dllexport) void del_net_names (char *template)
  824. {
  825.         del_list_net_names (routed_list, template);
  826. }
  827.  
  828. /* added 8 March 2000 for PC support */
  829.  
  830. __declspec(dllexport) void ensure_env_var (char *name, char *defval)
  831. {
  832.         generic_info_t gen[1];
  833.         if (get_generic_value (&global_generics, name, gen) != IS_STRING)
  834.         {
  835.                 char sbuff[MAXIDLEN];
  836.                 gen->name = name;
  837.                 gen->typename = "env_string";
  838.                 /* cannot use $(1) type command line variables as
  839.                  *they are not passed here :  argc = 0 , argv = NULL*/
  840.                 expand_string (defval, sbuff, 0, NULL);
  841.                 gen->expr = compile_string (sbuff);
  842.                 gen->g_type = IS_ENV_VAL;
  843.                 gen->g_class = DEFAULT;
  844.  
  845.                 set_generic_value (&global_generics, gen);
  846.         };
  847. }
  848.  
  849. /* initialise default information used around the design database */
  850. __declspec(dllexport) void InitialiseData (void)
  851. {
  852.         generic_info_t gen[1];
  853.         InitialiseVersionStrings ();
  854.  
  855.         if (!default_vhdl_datatype)
  856.                 default_vhdl_datatype = calloc (1, sizeof (vhdl_t));
  857.         if (!default_vhdl_bustype)
  858.                 default_vhdl_bustype = calloc (1, sizeof (vhdl_t));
  859.  
  860.         /* if we are using VHDL then look at the VHDL bus formatting tail*/
  861.         if (get_generic_value (&global_generics, "vhdl_bit_type", gen) == IS_STRING)
  862.         {
  863.                 default_vhdl_datatype->basetype = strdup (gen->expr->left.s);
  864.         }
  865.         else
  866.                 default_vhdl_datatype->basetype = "std_logic";
  867.  
  868.         /* if we are using VHDL then look at the VHDL bus formatting tail*/
  869.         if (get_generic_value (&global_generics, "vhdl_bus_type", gen) == IS_STRING)
  870.         {
  871.                 default_vhdl_bustype->basetype = strdup (gen->expr->left.s);
  872.         }
  873.         else
  874.                 default_vhdl_bustype->basetype = "std_logic_vector";
  875.  
  876.         default_vhdl_bustype->expr =
  877.             compile_expression (TO, compile_constant (0), compile_constant (0));
  878.         default_vhdl_bustype->is_vector = 1; /* is this port a vector */
  879.         default_vhdl_bustype->is_downto = 1; /* is the vector X TO Y or X DOWNTO Y  */
  880.  
  881.         /* look up VERTICAL_INIT and give it a default value if unknown */
  882.         ensure_env_var ("VERTICAL_INIT", VERTICAL_INI_PATH);
  883.  
  884.         ensure_env_var ("VERTICAL_PATH", VERTICAL_PATH);
  885. }
  886.  
  887. __declspec(dllexport) char *decode_which_list (net_t **list_head)
  888. {
  889.         if (list_head == NULL)
  890.                 return "No List";
  891.         if (list_head == &routed_list)
  892.                 return "routed list";
  893.         if (list_head == &named_list)
  894.                 return "named list";
  895.         if (list_head == &unrouted_list)
  896.                 return "unrouted list";
  897.         return "ERROR : unknown";
  898. }
  899.