Subversion Repositories Vertical

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 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
}