Subversion Repositories Vertical

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/* $Id: print_vhdl.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $ */
2
/*
3
 * $Log: print_vhdl.c,v $
4
 * Revision 1.1.1.1  2003/11/04 23:34:57  mjames
5
 * Imported into local repositrory
6
 *
7
 * Revision 1.17  2003/01/02 21:37:16  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.16  2002/09/30 13:23:05  MJAMES
16
 * Modified partition rules to include 'default assignment on declaration'
17
 * which maps to inputs being driven with default values on
18
 * productuion of a partition.
19
 *
20
 * signal c : std_logic := '0';
21
 *
22
 * becomes
23
 *
24
 * signal c: std_logic;
25
 *
26
 * begin
27
 *   c<= '0';
28
 *
29
 * Revision 1.15  2002/09/27 22:35:33  MJAMES
30
 * Added lhs_expr for cases like
31
 *
32
 * x(0) <= y
33
 *
34
 * where x is std_logic_vector(0 downto 0) and y is std_logic.
35
 *
36
 * Also added printing for default values on signals : this to be extended
37
 *
38
 * Revision 1.14  2002/09/09 10:12:02  mjames
39
 * Moved pin remapping function to pin ident editing function from
40
 * sorting pin name routine.
41
 *
42
 * Revision 1.13  2002/08/23 14:19:19  mjames
43
 * Introduced bundles and external sockets to VHDL from the Verilog printer.
44
 *
45
 * Revision 1.12  2001/12/13 22:18:52  mjames
46
 * Using #ident with header to identify file
47
 *
48
 * Corrected an attempt to reference a null net
49
 *
50
 * Revision 1.11  2001/11/19 10:41:35  mjames
51
 * Merged back DTC release
52
 *
53
 * Revision 1.10.2.1  2001/11/15 22:25:39  mjames
54
 * Removed unused variables, added brackets
55
 *
56
 * Revision 1.10  2001/11/01 11:04:36  mjames
57
 * Pin node identifier is printed out in a component declaration rather than
58
 * node name which is more a property of the attached net.
59
 *
60
 * Revision 1.9  2001/10/31 22:20:12  mjames
61
 * Tidying up problematical comments caused by CVS
62
 * 'intelligent' comment guessing
63
 *
64
 * Revision 1.8  2001/10/10 20:18:22  mjames
65
 * Added a vert_regcomp function to compile regular expressions
66
 * with '^' (match start string) and  '$' (match end string) bracketing
67
 * this => wildcard must match entire string not just a part of it.
68
 *
69
 * Revision 1.7  2001/09/21 14:22:27  mjames
70
 * Added prefix to instance name in order to avoid a Model Technology name
71
 * space collision  e.g.
72
 *
73
 * U1 : U1 port map () ...
74
 *
75
 * Now prints
76
 *
77
 * I_U1 : U1 port map which is safer.
78
 *
79
 * Revision 1.6  2001/06/22 11:06:19  mjames
80
 * Modified to tag VHDL code generated so that
81
 * Vertical can recognise it.
82
 *
83
 * Revision 1.5  2001/06/20 13:45:40  mjames
84
 * For all components defined by 'Component' declarations, forced the
85
 * printout of only one component for several instances sharing the same component declaration.
86
 *
87
 * Revision 1.4  2001/06/06 12:10:19  mjames
88
 * Move from HPUX
89
 *
90
 * Revision 1.3  2001/04/27 08:08:44  mjames
91
 * Extra tidying of the print_vhdl code
92
 *
93
 * Revision 1.2  2000/11/29 21:51:18  mjames
94
 * Fine tuning of software
95
 *
96
 * Revision 1.1.1.1  2000/10/19 21:58:39  mjames
97
 * Mike put it here
98
 *
99
 *
100
 * Revision 1.23  2000/10/12  15:32:32  15:32:32  mjames (Mike James)
101
 * Removed <cr>
102
 *
103
 * Revision 1.22  2000/10/12  14:25:55  14:25:55  mjames (Mike James)
104
 * changed listing vhdl signals to expand expressions
105
 * until a constant is located
106
 *
107
 * Revision 1.21  2000/10/04  10:37:08  10:37:08  mjames (Mike James)
108
 * Modified for Vertical2 : support COMPONENTS and SIGNALS
109
 *
110
 * Revision 1.21  2000/10/04  10:37:08  10:37:08  mjames (Mike James)
111
 * Part of Release PSAVAT01
112
 *
113
 * Revision 1.20  2000/10/02  11:04:17  11:04:17  mjames (Mike James)
114
 * new_vhdl
115
 *
116
 * Revision 1.18  2000/09/21  10:15:48  10:15:48  mjames (Mike James)
117
 * Part of Release Sep21Alpha
118
 *
119
 * Revision 1.17  2000/08/25  09:57:14  09:57:14  mjames (Mike James)
120
 * Part of Release Aug25_alpha
121
 *
122
 * Revision 1.16  2000/08/25  09:55:33  09:55:33  mjames (Mike James)
123
 * Corrected for the disappearance of generic information
124
 *
125
 * Revision 1.15  2000/08/16  08:57:30  08:57:30  mjames (Mike James)
126
 * Part of Release CD01_Aug2000
127
 *
128
 * Revision 1.14  2000/08/14  14:45:11  14:45:11  mjames (Mike James)
129
 * Part of Release Aug_14_2000
130
 *
131
 * Revision 1.13  2000/08/14  14:43:15  14:43:15  mjames (Mike James)
132
 * Added power pins
133
 *
134
 * Revision 1.12  2000/08/11  08:30:32  08:30:32  mjames (Mike James)
135
 * Part of Release Aug_11_2000
136
 *
137
 * Revision 1.11  2000/08/09  10:31:47  10:31:47  mjames (Mike James)
138
 * Part of Release Aug__9_2000
139
 *
140
 * Revision 1.10  2000/05/31  11:42:56  11:42:56  mjames (Mike James)
141
 * Part of Release May_31_2000
142
 *
143
 * Revision 1.9  2000/05/08  17:01:37  17:01:37  mjames (Mike James)
144
 * Part of Release May__8_2000
145
 *
146
 * Revision 1.8  2000/05/08  16:59:30  16:59:30  mjames (Mike James)
147
 * Part of Release May__8_2000
148
 *
149
 * Revision 1.7  2000/05/08  16:57:07  16:57:07  mjames (Mike James)
150
 * Part of Release May__8_2000
151
 *
152
 * Revision 1.6  2000/03/08  16:19:22  16:19:22  mjames (Mike James)
153
 * New version including PC
154
 *
155
 * Revision 1.3  2000/01/20  15:58:47  15:58:47  mjames (Mike James)
156
 * Part of Release R22
157
 *
158
 * Revision 1.2  99/12/22  11:15:28  11:15:28  mjames (Mike James)
159
 * Part of Release Dec_22_1999
160
 *
161
 * Revision 1.1  99/11/23  13:52:14  13:52:14  mjames (Mike James)
162
 * Initial revision
163
 *
164
 */
165
 
166
#include "print_vhdl.h"
167
 
168
#include "cmdlog.h"
169
#include "cmdparse.h"
170
#include "database.h"
171
#include "expression.h"
172
#include "generic.h"
173
#include "print_vlog.h"
174
#include "printout.h"
175
#include "sorting.h"
176
#include "vertcl_main.h"
177
 
178
#include <ctype.h>
179
#include <regex.h>
180
#include <stdio.h>
181
#include <stdlib.h>
182
#include <string.h>
183
#include <time.h>
184
/* for streq */
185
#include "lx_support.h"
186
/* ********************************************************************** */
187
 
188
/* Decoding pin direction in VHDL */
189
static char *decode_pin_VHDL[] = {"-NONE-",
190
                                  "IN",
191
                                  "OUT",
192
                                  "BUFFER", /* buffer is a sort of Output pin */
193
                                  "INOUT",
194
                                  "CONFIG_PIN",
195
                                  "POWER_PIN"};
196
/* ********************************************************************** */
197
/* VHDL output of the entities                                            */
198
/* ********************************************************************** */
199
static char illegal[] = "$:|/.\\ ";
200
static char replace[] = "Sxxxxx_";
201
 
202
char *make_vhdl_name (char *buffer, char *str)
203
{
204
        int i, j, l;
205
        buffer[0] = 0;
206
        if (str)
207
        {
208
                strcpy (buffer, str); /* should be a call to strncpy !! */
209
        }
210
        l = strlen (buffer);
211
        /* edit out illegal strings from the net name */
212
        for (i = 0; i < l; i++)
213
        {
214
                for (j = 0; j < sizeof (illegal); j++)
215
                        if (buffer[i] == illegal[j])
216
                                buffer[i] = replace[j];
217
        }
218
        i = l - 1;
219
        /* convert pin indices back from Altera form if we are looking at FIT files */
220
        if (l)
221
        {
222
                /* name ends in underscore, this forces mapping name_nn_ --> name(nn) */
223
                if (buffer[i] == '_')
224
                {
225
                        buffer[i--] = ')';
226
                        while (i >= 0 && buffer[i] != '_')
227
                                i--;
228
                        if (i >= 0)
229
                                buffer[i] = '(';
230
                }
231
        }
232
        return buffer;
233
}
234
 
235
/* ********************************************************************** */
236
/* decodes the 'vector' part of a bus , if known                           */
237
void decode_vhdl_bus (FILE *f, vhdl_t *vhdl, generic_print_style recurse_generics)
238
{
239
        if (!vhdl)
240
                vhdl = default_vhdl_datatype;
241
        if (vhdl->is_vector)
242
                print_range_expression (f, vhdl->expr, recurse_generics);
243
}
244
 
245
/* ********************************************************************** */
246
 
247
void decode_vhdl_type (FILE *f, vhdl_t *vhdl, generic_print_style recurse_generics)
248
{
249
        /* avoid crashing on a null pointer */
250
        if (!vhdl)
251
                vhdl = default_vhdl_datatype;
252
        fprintf (f, "%s ", vhdl->basetype);
253
        if (vhdl->is_vector)
254
                decode_vhdl_bus (f, vhdl, recurse_generics);
255
}
256
 
257
/* ********************************************************************** */
258
 
259
/* print out a VHDL component declaration */
260
void print_VHDL_component (FILE *f, socket_t *dev, int All)
261
{
262
        node_t *n;
263
        /* sort the identifiers of the nodes */
264
        sort_nodes (dev, NO_EXTRACT_XY);
265
 
266
        fprintf (f, "COMPONENT  %s\n", check_null_str (dev->type));
267
        fprintf (f, "--  DEV_IDENT \"%s\"\n\n", check_null_str (dev->identifier));
268
        if (dev->is_template)
269
                fprintf (f, "--  Defined by COMPONENT definition\n");
270
 
271
        if (dev->generics)
272
                list_VHDL_generic_values (f, &dev->generics);
273
 
274
        fprintf (f, "  PORT ( \n");
275
        /* sort the identifiers of the nodes */
276
        sort_nodes (dev, NO_EXTRACT_XY);
277
        n = dev->nodes;
278
        while (n)
279
        {
280
                vhdl_t *pin_datatype = default_vhdl_datatype;
281
                expression_t *default_expr = NULL;
282
                char nam[MAXIDLEN];
283
                if (n->orig_vhdltype)
284
                {
285
                        pin_datatype = n->orig_vhdltype;
286
                        default_expr = n->orig_vhdltype->default_expr;
287
                }
288
                else if (n->vhdltype)
289
                {
290
                        pin_datatype = n->vhdltype;
291
                        default_expr = n->vhdltype->default_expr;
292
                }
293
                if ((n->net_assigned && n->in_use) || (All || dev->is_template))
294
                {
295
                        fprintf (
296
                            f,
297
                            "  %-16s : %6s  ",
298
                            make_vhdl_name (nam, check_null_str (n->identifier)), /* was
299
                                                                                     n->name */
300
                            decode_pin_VHDL[(int) n->pindir]);
301
                        decode_vhdl_type (f, pin_datatype, NO_RECURSE); /* until a generic
302
                                                                           found */
303
                        /* ought to be optional dependent on synthesis style */
304
                        if (default_expr)
305
                        {
306
                                fprintf (f, ":= ");
307
                                print_expression (f, default_expr, NO_RECURSE);
308
                        }
309
 
310
                        if (n->sktnext)
311
                                fprintf (f, ";");
312
                        fprintf (f, " -- i=%s r=%d --\n", n->identifier, n->refcount);
313
                }
314
                n = n->sktnext; /* traverse to next pin on socket */
315
        };
316
        fprintf (f, ");\nEND COMPONENT;\n\n");
317
}
318
 
319
/* ********************************************************************** */
320
/* Printout an instance of a component */
321
/* ********************************************************************** */
322
void print_VHDL_instance (FILE *f, socket_t *dev, int All)
323
{
324
        node_t *n;
325
        int need_term = 0;
326
        char *prefix;
327
        /* only prefix devices with similar idents and types */
328
        if (!ISNULLSTR (dev->identifier) && !ISNULLSTR (dev->type) &&
329
            streq (dev->identifier, dev->type))
330
        {
331
                prefix = "I_";
332
        }
333
        else
334
        {
335
                prefix = "";
336
        }
337
 
338
        fprintf (
339
            f,
340
            "%s%s : %s \n",
341
            prefix,
342
            check_null_str (dev->identifier),
343
            check_null_str (dev->type));
344
 
345
        if (dev->generics)
346
                list_VHDL_generic_map_values (f, &dev->generics);
347
 
348
        fprintf (f, "  PORT MAP ( \n");
349
        /* sort the identifiers of the nodes */
350
        sort_nodes (dev, NO_EXTRACT_XY);
351
        n = dev->nodes;
352
        while (n)
353
        {
354
                vhdl_t *pin_datatype = default_vhdl_datatype;
355
                char nam1[MAXIDLEN], nam2[MAXIDLEN];
356
                if (n->vhdltype)
357
                        pin_datatype = n->vhdltype;
358
                if ((n->net_assigned && n->in_use) || All)
359
                {
360
                        char *sig_prefix;
361
                        if (need_term)
362
                                fprintf (f, ",\n");
363
                        else
364
                                fprintf (f, "\n");
365
                        need_term = 1;
366
                        /* is there a slice in the output */
367
                        if (n->net && n->net->needs_buff_sig)
368
                                sig_prefix = BUFPREFIX;
369
                        else
370
                                sig_prefix = "";
371
 
372
                        if (n->net)
373
                        {
374
                                fprintf (
375
                                    f,
376
                                    "  %s",
377
                                    make_vhdl_name (
378
                                        nam1, check_null_str (n->identifier))); /* was n->name
379
                                                                                 */
380
                                if (n->lhs_expr)
381
                                {
382
                                        print_range_expression (f, n->lhs_expr, RECURSE_CONST);
383
                                }
384
                                fprintf (
385
                                    f,
386
                                    "=> %s%s ",
387
                                    sig_prefix,
388
                                    make_vhdl_name (nam2, check_null_str (n->net->name)));
389
                        }
390
                        else
391
                        {
392
                                fprintf (
393
                                    f,
394
                                    "  %-20s => OPEN ",
395
                                    make_vhdl_name (
396
                                        nam1, check_null_str (n->identifier))); /* was n->name
397
                                                                                 */
398
                        }
399
                        /* do bus slicing only if the connected net is a bus */
400
                        if (n->net && n->net->vhdltype)
401
                        {
402
                                decode_vhdl_bus (f, n->net->vhdltype, RECURSE_CONST);
403
                        }
404
                        else
405
                        {
406
                                /*  fprintf(f,"\n"); */
407
                        }
408
                }
409
                n = n->sktnext; /* traverse to next pin on socket */
410
        };
411
        fprintf (f, "\n   );\n\n");
412
}
413
 
414
/* ********************************************************************** */
415
 
416
void print_VHDL_sigs (FILE *f)
417
{
418
        net_t *net = named_list;
419
        char nam[MAXIDLEN], *sig_prefix;
420
        while (net)
421
        {
422
                if (net->needs_buff_sig)
423
                        sig_prefix = BUFPREFIX;
424
                else
425
                        sig_prefix = "";
426
                /* May 21 2001 only print nets that connect to 'external' tagged modules */
427
                if ((IS_ROUTABLE (net->how_routed)) &&
428
                    ((net->bundle_member) || ((net->inside_partition) && net->has_external)))
429
                {
430
                        fprintf (f, "    ");
431
                }
432
                else
433
                {
434
                        fprintf (f, "  --");
435
                }
436
 
437
                fprintf (f, " signal %s%s : ", sig_prefix, make_vhdl_name (nam, net->name));
438
                decode_vhdl_type (f, net->vhdltype, RECURSE_CONST);
439
                if (net->vhdltype)
440
                {
441
                        if (net->vhdltype->decl_expr)
442
                        {
443
                                print_expression (f, net->vhdltype->decl_expr, NO_RECURSE);
444
                        }
445
                        if (net->vhdltype->default_expr)
446
                        {
447
                                fprintf (f, ":= ");
448
                                print_expression (f, net->vhdltype->default_expr, NO_RECURSE);
449
                        }
450
                }
451
                fprintf (
452
                    f,
453
                    "; -- partition : %s %s %s %s %s\n",
454
                    net->inside_partition ? "used in," : "unused in,",
455
                    net->leaves_partition ? "leaves," : "buried,",
456
                    net->needs_buff_sig ? ", buffered," : "",
457
                    net->has_external ? "external skt" : "internal skt",
458
                    net->bundle_member ? "bundle member" : " not bundled");
459
                net = net->next;
460
        }
461
}
462
/* ********************************************************************** */
463
 
464
void print_VHDL_assignments (FILE *f)
465
{
466
        net_t *net = named_list;
467
        socket_t *socket = socket_head;
468
 
469
        /* code borrowed from Verilog */
470
        fprintf (f, "-- Bundled signals\n\n");
471
 
472
        while (socket)
473
        {
474
                node_t *nodes = socket->nodes;
475
                if (socket->highest_bundle &&
476
                    (socket->bundle_width > MINBUNDLE)) /* will not do assigns on small bundles
477
                                                         */
478
                        while (nodes)
479
                        {
480
                                if (nodes->bundle_index >= 0)
481
                                {
482
                                        char nam[MAXIDLEN];
483
                                        net_t *net = nodes->net;
484
                                        make_vhdl_name (nam, net->name);
485
                                        fprintf (
486
                                            f,
487
                                            " %s <= %s(%d);\n",
488
                                            nam,
489
                                            socket->identifier,
490
                                            nodes->bundle_index);
491
                                }
492
                                nodes = nodes->sktnext;
493
                        }
494
                /*    else
495
                      fprintf(f,"-- %s;\n",
496
                               net->name);
497
                */
498
 
499
                socket = socket->next;
500
        }
501
 
502
        fprintf (f, "-- Buffered signals\n\n");
503
        while (net)
504
        {
505
                if (net->inside_partition && net->needs_buff_sig)
506
                {
507
                        char nam[MAXIDLEN];
508
                        make_vhdl_name (nam, net->name),
509
 
510
                            fprintf (f, " %-20s <= " BUFPREFIX "%s; -- buffer\n", nam, nam);
511
                }
512
                if (net->vhdl_connect_net && net->subnets)
513
                {
514
                        char nam[MAXIDLEN], nam1[MAXIDLEN];
515
                        make_vhdl_name (nam, net->identifier);
516
                        make_vhdl_name (nam1, net->subnets->identifier);
517
                        fprintf (f, " %-20s <= %s; -- connector\n", nam, nam1);
518
                }
519
                else if (net->inside_partition && net->vhdltype && net->vhdltype->default_expr)
520
                {
521
                        char nam[MAXIDLEN];
522
                        make_vhdl_name (nam, net->identifier);
523
                        fprintf (f, " %-20s <= ", nam);
524
                        print_range_expression (f, net->vhdltype->default_expr, NO_RECURSE);
525
                        fprintf (f, "; -- Defined default drive value\n");
526
                }
527
 
528
                net = net->next;
529
        }
530
        fprintf (f, "-- \n\n");
531
}
532
 
533
/* ********************************************************************** */
534
/* code lists bundles although they are probably broken */
535
void print_VHDL_entity (FILE *f, char *entityname)
536
{
537
        net_t *net;
538
        int need_term = 0;
539
        socket_t *skt;
540
        char nam[MAXIDLEN];
541
 
542
        fprintf (f, "ENTITY %s IS\n", entityname);
543
        /* print out global generic settings */
544
        /*
545
          list_VHDL_generic_values (f,&partition_generics);
546
        */
547
        fprintf (f, "  PORT (\n");
548
 
549
        skt = socket_head;
550
        /* bundles of pins are replaced by signals named the same as a socket which
551
           they are bundled through , unless the bundles are too small in which case they
552
           are replaced by separate wires */
553
        while (skt)
554
        {
555
                if (skt->highest_bundle)
556
                {
557
                        if (skt->bundle_width > MINBUNDLE)
558
                        {
559
                                if (need_term)
560
                                {
561
                                        fprintf (f, ";\n");
562
                                        need_term = 0;
563
                                }
564
                                else
565
                                {
566
                                        fprintf (f, "\n");
567
                                }
568
                                fprintf (
569
                                    f,
570
                                    "  %-15s : %6s %s (%d downto 0) ",
571
                                    make_vhdl_name (nam, skt->identifier),
572
                                    decode_pin_VHDL[BIDIR],
573
                                    default_vhdl_bustype->basetype,
574
                                    skt->bundle_width - 1);
575
 
576
                                need_term = 1;
577
                        }
578
                        else
579
                        /* if the 'bundle' has less than MINBUNDLE pins, */
580
                        /* list out all of the nets in turn as pins      */
581
                        {
582
                                node_t *node;
583
                                node = skt->nodes;
584
                                while (node)
585
                                {
586
                                        net = node->net;
587
                                        /*
588
                                            printf("node %s\n",node->identifier);
589
                                        */
590
                                        if (net && IS_ROUTABLE (net->how_routed) &&
591
                                            net->bundle_member)
592
                                        {
593
                                                if (need_term)
594
                                                {
595
                                                        fprintf (f, ";\n");
596
                                                        need_term = 0;
597
                                                }
598
                                                else
599
                                                {
600
                                                        fprintf (f, "\n");
601
                                                }
602
                                                fprintf (
603
                                                    f,
604
                                                    "  %-15s : %6s ",
605
                                                    make_vhdl_name (nam, net->name),
606
                                                    decode_pin_VHDL[net->ext_dir]);
607
                                                decode_vhdl_type (
608
                                                    f, net->vhdltype, RECURSE_NUMBER);
609
                                                need_term = 1;
610
                                        }
611
                                        node = node->sktnext;
612
                                }
613
                        }
614
                }
615
 
616
                skt = skt->next;
617
        }
618
 
619
        /* go back and list all of the non-bundle pins */
620
 
621
        net = named_list;
622
 
623
        while (net)
624
        {
625
                /* print out only unbundled nets as ports of the pcb */
626
                if (net->leaves_partition && !net->bundle_member)
627
                {
628
                        if (need_term)
629
                        {
630
                                fprintf (f, ";\n");
631
                        }
632
                        else
633
                        {
634
                                fprintf (f, "\n");
635
                        }
636
                        fprintf (
637
                            f,
638
                            "  %-15s : %6s ",
639
                            make_vhdl_name (nam, net->name),
640
                            decode_pin_VHDL[net->ext_dir]);
641
                        decode_vhdl_type (f, net->vhdltype, RECURSE_NUMBER);
642
 
643
                        need_term = 1;
644
                }
645
                net = net->next;
646
        }
647
        fprintf (f, "\n     );\n");
648
        fprintf (f, "END %s;\n\n", entityname);
649
}
650
 
651
/* ********************************************************************** */
652
/* generate default VHDL Libraries */
653
/* ********************************************************************** */
654
void print_VHDL_libs (FILE *f)
655
{
656
        fprintf (f, "LIBRARY IEEE,WORK;\nUSE IEEE.std_logic_1164.ALL;\n\n");
657
}
658
 
659
/* ********************************************************************** */
660
/* generate a VHDL architecture forselected sockets */
661
/* ********************************************************************** */
662
void print_VHDL_architecture (FILE *f, char *entityname)
663
{
664
        socket_t *skt;
665
        char *arch_name;
666
        generic_info_t gen[1];
667
        /* if we are using VHDL then look at the VHDL architecture name if  defined*/
668
 
669
        arch_name =
670
            (get_generic_value (&global_generics, "vhdl_arch_name", gen) == IS_ENV_VAL &&
671
             gen->expr)
672
                ? gen->expr->left.s
673
                : "top_arch";
674
        fprintf (f, "\n\nARCHITECTURE %s OF  %s IS\n\n", arch_name, entityname);
675
        /* not allowed to have generics at the top level so put them here */
676
        list_VHDL_constants (f, &partition_generics);
677
 
678
        list_VHDL_constants (f, &global_generics);
679
        /* clear type seen flags on all socket templates = components */
680
        clr_type_seen ();
681
 
682
        skt = socket_head;
683
        /* list out templates for those sockets selected */
684
        while (skt)
685
        {
686
                if (skt->is_external && skt->highest_bundle == 0)
687
                {
688
                        /* suppress printout of duplicate components .... */
689
                        if (skt->template_socket)
690
                        {
691
                                if (skt->template_socket->socket_type_seen == 0)
692
                                {
693
                                        print_VHDL_component (f, skt->template_socket, 0);
694
                                        skt->template_socket->socket_type_seen = 1;
695
                                }
696
                        }
697
                        else
698
                                /* no components, use socket/entity as its own component */
699
                                print_VHDL_component (f, skt, 0);
700
                }
701
                skt = skt->next;
702
        }
703
 
704
        print_VHDL_sigs (f);
705
        fprintf (f, "\n\nBEGIN\n\n");
706
        skt = socket_head;
707
        while (skt)
708
        {
709
                if (skt->is_external && skt->highest_bundle == 0)
710
                        print_VHDL_instance (f, skt, 0);
711
                skt = skt->next;
712
        }
713
        print_VHDL_assignments (f);
714
        fprintf (f, "END %s;\n\n", arch_name);
715
}
716
 
717
/* ********************************************************************** */
718
/* generate a VHDL file */
719
/* ********************************************************************** */
720
 
721
void produce_VHDL (FILE *f, char *entityname, char *template)
722
{
723
        char linebuff[256];
724
        int done_entity = 0, done_architecture = 0;
725
        if (!template || !template[0])
726
        { /* check null pointer or empty string */
727
                fprintf (f, "-- vertical vhdl\n");
728
                print_header (f, "WRITE VHDL");
729
                print_VHDL_libs (f);
730
                fprintf (f, "\n-- vertical read_off\n");
731
                print_VHDL_entity (f, entityname);
732
                fprintf (f, "\n-- vertical read_on\n");
733
                print_VHDL_libs (f);
734
                print_VHDL_architecture (f, entityname);
735
                fprintf (f, "\n-- vertical end;\n");
736
        }
737
        else
738
        { /* there is a template file */
739
                FILE *tp;
740
                tp = fopen (template, "r");
741
                if (tp)
742
                {
743
                        fprintf (f, "-- vertical vhdl\n");
744
                        print_header (f, "WRITE VHDL");
745
                        fprintf (f, "-- Using template '%s'\n", template);
746
                        while (!feof (tp))
747
                        {
748
                                if (fgets (linebuff, 256, tp))
749
                                {
750
                                        if (strstr (linebuff, "$ENT"))
751
                                        {
752
                                                fprintf (f, "\n-- vertical read_off\n");
753
                                                print_VHDL_entity (f, entityname);
754
                                                fprintf (f, "\n-- vertical read_on\n");
755
                                                done_entity++;
756
                                        }
757
                                        else if (strstr (linebuff, "$ARCH"))
758
                                        {
759
                                                print_VHDL_architecture (f, entityname);
760
                                                done_architecture++;
761
                                        }
762
                                        else
763
                                                fprintf (f, "%s", linebuff); /* it already has
764
                                                                                a '\n' on the
765
                                                                                end */
766
                                }
767
                        }
768
                        fprintf (f, "\n-- vertical end;\n");
769
                        fclose (tp);
770
                        if (done_entity != 1)
771
                                Log (
772
                                    LOG_ERROR,
773
                                    "-- Error: %d  $ENT$ tags counted in template '%s'\n",
774
                                    template);
775
                        if (done_architecture != 1)
776
                                Log (
777
                                    LOG_ERROR,
778
                                    "-- Error: %d  $ARCH$ tags counted in template '%s'\n",
779
                                    template);
780
                }
781
                else
782
                        Log (
783
                            LOG_ERROR,
784
                            "-- Error: Cannot open VHDL  template '%s'\n",
785
                            template);
786
        }
787
}