Subversion Repositories Vertical

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/*
2
 * $Id: print_vlog.c,v 1.2 2004/06/22 21:44:14 mjames Exp $
3
 *
4
 * $Log: print_vlog.c,v $
5
 * Revision 1.2  2004/06/22 21:44:14  mjames
6
 * Firrst build most files
7
 *
8
 * Revision 1.28  2002/09/09 10:11:27  mjames
9
 * Moved pin remapping function to pin ident editing function from
10
 * sorting pin name routine.
11
 *
12
 * Revision 1.27  2002/08/23 14:18:02  mjames
13
 * Removed some constants to the header file
14
 *
15
 * Revision 1.26  2002/01/21 09:27:49  mjames
16
 * Filtering of not routable nets was not 100% complete. Added
17
 * code for this. Also a comma was suppressed on the first port listed on
18
 * a top level component declaration, if this was a member of a bundle with less
19
 * than (currently) 4 pins.
20
 *
21
 * Revision 1.25  2001/12/24 20:05:18  mjames
22
 * Prevented wires being listed if not routable.
23
 * Printing net names rather than identifiers.
24
 *
25
 * Revision 1.24  2001/12/20 13:37:34  mjames
26
 * Small bundles printed as induvidual signals
27
 *
28
 * Revision 1.23  2001/12/11 20:32:23  mjames
29
 * Implemented  regular expression pin  name editing
30
 * Allows for elimination of pin_xx prefixing (as this is wrong for
31
 * many verilog netlist)
32
 *
33
 * Revision 1.22  2001/11/19 10:41:35  mjames
34
 * Merged back DTC release
35
 *
36
 * Revision 1.21.2.1  2001/11/15 22:04:43  mjames
37
 * Removed unused variables
38
 *
39
 * Revision 1.21  2001/10/31 22:20:13  mjames
40
 * Tidying up problematical comments caused by CVS
41
 * 'intelligent' comment guessing
42
 *
43
 * Revision 1.20  2001/10/31 16:20:06  mjames
44
 * fixed fpga alternate file printing to work in all cases.
45
 *
46
 * Revision 1.19  2001/10/22 10:57:52  mjames
47
 * Identify bundle attributes with its declaration
48
 * Allow the user to define a replacement string for the
49
 * set fpga <socket_id> "string"
50
 * which is printed out instead of the component declaration
51
 *
52
 * Revision 1.18  2001/10/11 11:52:32  mjames
53
 * Syntax is now checked as compatible with Certify
54
 *
55
 * Revision 1.17  2001/10/10 20:18:22  mjames
56
 * Added a vert_regcomp function to compile regular expressions
57
 * with '^' (match start string) and  '$' (match end string) bracketing
58
 * this => wildcard must match entire string not just a part of it.
59
 *
60
 * Revision 1.16  2001/09/16 20:36:03  mjames
61
 * Second attempt to modify wire bundles to be connector rather than net
62
 * centric. Allows more than one connector to carry the same net,
63
 *
64
 * Revision 1.15  2001/09/16 19:49:34  mjames
65
 * Second attempt at bundling the pins on sockets
66
 *
67
 * Revision 1.14  2001/09/13 21:07:18  mjames
68
 * Printing of wire bundles in place of induvidual pins for Ceritfy support.
69
 *
70
 * Revision 1.13  2001/08/09 20:30:37  mjames
71
 * Needed to write net name not identifier carried on net when listing device pins
72
 *
73
 * Revision 1.12  2001/07/16 15:55:14  MJAMES
74
 * Conversion to correctly print port list of  extracted components.
75
 *
76
 * Revision 1.11  2001/07/12 09:12:10  mjames
77
 * Commented out dead function to do with printing signal types:
78
 * This was a hangover from VHDL printing.
79
 *
80
 * Revision 1.10  2001/06/22 11:06:49  mjames
81
 * Modified to tag Verilog code generated so that
82
 * Vertical can recognise it.
83
 *
84
 * Revision 1.9  2001/06/19 05:21:26  mjames
85
 * Fine tuning to try and reproduce files that are compatible with
86
 * Certify
87
 *
88
 * Revision 1.8  2001/06/07 13:34:22  MJAMES
89
 * Correctly removing unused nets from printouts
90
 *
91
 * Revision 1.7  2001/06/06 12:10:19  mjames
92
 * Move from HPUX
93
 *
94
 * Revision 1.6  2001/04/06 22:47:02  mjames
95
 * Added doc2, the creator of documentation to Vertical scripts uses PERL
96
 *
97
 *
98
 * Also correcting generic behaviour and the printing of Verilog.
99
 *
100
 * Revision 1.5  2001/04/04 22:12:31  mjames
101
 * Added some online documentation to the C program command handler
102
 * THis is scanned by a utility called 'doc' that currently creates
103
 * simple HTML from part formatted C comments
104
 *
105
 * Also working well on printing VERILOG
106
 *
107
 * still have problems with C comments and VERTICAL pragmas.
108
 *
109
 * Revision 1.4  2001/03/29 22:08:56  mjames
110
 * Modified to define the scope of set generic commands : now can be global
111
 * or defined for a socket or a simple wildcarded list of sockets.
112
 *
113
 * In addition the is_FPGA property has been activated so that FPGA components
114
 * are not listed out when used in a Verilog (.vb) file.
115
 *
116
 * Version raised to 11.02
117
 *
118
 * Revision 1.3  2001/03/29 08:27:07  mjames
119
 * Converted frbread for use with the newer files from the drawing office
120
 *
121
 * Revision 1.2  2001/01/02 07:53:53  mjames
122
 * Made changes to allow for interface with TCL/Tk
123
 *
124
 * Revision 1.1.1.1  2000/10/19 21:58:39  mjames
125
 * Mike put it here
126
 *
127
 *
128
 * Revision 1.21  2000/10/04  10:37:08  10:37:08  mjames (Mike James)
129
 * Modified for Vertical2 : support COMPONENTS and SIGNALS
130
 *
131
 * Revision 1.21  2000/10/04  10:37:08  10:37:08  mjames (Mike James)
132
 * Part of Release PSAVAT01
133
 *
134
 * Revision 1.20  2000/10/02  11:04:18  11:04:18  mjames (Mike James)
135
 * new_vhdl
136
 *
137
 * Revision 1.19  2000/09/27  14:42:18  14:42:18  mjames (Mike James)
138
 * Part of Release Sep_27_ST_2000
139
 *
140
 * Revision 1.18  2000/09/21  10:15:48  10:15:48  mjames (Mike James)
141
 * Part of Release Sep21Alpha
142
 *
143
 * Revision 1.17  2000/08/25  09:57:14  09:57:14  mjames (Mike James)
144
 * Part of Release Aug25_alpha
145
 *
146
 * Revision 1.16  2000/08/16  08:57:30  08:57:30  mjames (Mike James)
147
 * Part of Release CD01_Aug2000
148
 *
149
 * Revision 1.15  2000/08/14  14:45:12  14:45:12  mjames (Mike James)
150
 * Part of Release Aug_14_2000
151
 *
152
 * Revision 1.14  2000/08/14  14:43:27  14:43:27  mjames (Mike James)
153
 * Added power pins
154
 *
155
 * Revision 1.13  2000/08/11  14:17:18  14:17:18  mjames (Mike James)
156
 * Failed to suppress declaring internal components
157
 * when printing verilog.
158
 *
159
 * Revision 1.12  2000/08/11  08:30:32  08:30:32  mjames (Mike James)
160
 * Part of Release Aug_11_2000
161
 *
162
 * Revision 1.11  2000/08/09  10:31:47  10:31:47  mjames (Mike James)
163
 * Part of Release Aug__9_2000
164
 *
165
 * Revision 1.10  2000/05/31  11:42:57  11:42:57  mjames (Mike James)
166
 * Part of Release May_31_2000
167
 *
168
 * Revision 1.9  2000/05/08  17:01:38  17:01:38  mjames (Mike James)
169
 * Part of Release May__8_2000
170
 *
171
 * Revision 1.8  2000/05/08  16:59:31  16:59:31  mjames (Mike James)
172
 * Part of Release May__8_2000
173
 *
174
 * Revision 1.7  2000/05/08  16:57:07  16:57:07  mjames (Mike James)
175
 * Part of Release May__8_2000
176
 *
177
 * Revision 1.6  2000/03/08  16:19:23  16:19:23  mjames (Mike James)
178
 * New version including PC
179
 *
180
 * Revision 1.3  2000/01/20  15:58:47  15:58:47  mjames (Mike James)
181
 * Part of Release R22
182
 *
183
 * Revision 1.2  99/12/22  11:15:28  11:15:28  mjames (Mike James)
184
 * Part of Release Dec_22_1999
185
 *
186
 * Revision 1.1  99/11/23  13:52:43  13:52:43  mjames (Mike James)
187
 * Initial revision
188
 *
189
 */
190
 
191
#include "cmdlog.h"
192
#include "cmdparse.h"
193
#include "database.h"
194
#include "expression.h"
195
#include "generic.h"
196
#include "print_vhdl.h"
197
#include "printout.h"
198
#include "sorting.h"
199
#include "vertcl_main.h"
200
 
201
#include <ctype.h>
202
#include <regex.h>
203
#include <stdio.h>
204
#include <stdlib.h>
205
#include <string.h>
206
#include <time.h>
207
 
208
/* ********************************************************************** */
209
 
210
/* Decoding pin direction in VLOG */
211
static char *decode_pin_VLOG[] = {"inout", /* was -NONE- */
212
                                  "inout", /* was in */
213
                                  "out",
214
                                  "out", /* buffer is a sort of Output pin */
215
                                  "inout",
216
                                  "inout",  /* config is a sort of input pin */
217
                                  "inout"}; /* power is a sort of input pin */
218
 
219
/* ********************************************************************** */
220
/* VHDL output of the entities                                            */
221
/* ********************************************************************** */
222
static char illegal[] = "-+:|/.\\$ ";
223
static char replace[] = "NPCxxxxS_";
224
char *make_VLOG_name (char *buffer, char *str)
225
{
226
        int i, l, j;
227
 
228
        l = strlen (str);
229
        if (isdigit (str[0]))
230
        {
231
                l += 1;
232
                sprintf (buffer, "\%s", str); /* might as well use the verilog quotation method
233
                                                 in this case */
234
        }
235
        else
236
                strcpy (buffer, str);
237
 
238
        /* spot illegal strings in the net name */
239
        for (i = 0; i < l; i++)
240
        {
241
                for (j = 0; j < sizeof (illegal); j++)
242
                        if (buffer[i] == illegal[j])
243
                                buffer[i] = replace[j];
244
        }
245
 
246
        i = l - 1;
247
        /* convert pin indices back from Altera form if we are looking at FIT files */
248
        if (l)
249
        {
250
                /* name ends in underscore, this forces mapping name_nn_ --> name(nn) */
251
                if (buffer[i] == '_')
252
                {
253
                        buffer[i--] = ']';
254
                        while (i >= 0 && buffer[i] != '_')
255
                                i--;
256
                        if (i >= 0)
257
                                buffer[i] = '[';
258
                }
259
        }
260
        return buffer;
261
}
262
 
263
/* ********************************************************************** */
264
/* decodes the 'vector' part of a bus , if known                           */
265
int decode_VLOG_bus (FILE *f, vhdl_t *vhdl)
266
{
267
        if (!vhdl)
268
                vhdl = default_vhdl_datatype;
269
 
270
        if (vhdl->is_vector)
271
        {
272
                int bus_high, bus_low;
273
                bus_high = 0;
274
                bus_low = 0;
275
                eval_vhdl_expression (vhdl->expr, &bus_high, &bus_low);
276
                if (bus_high == bus_low)
277
                        return fprintf (f, "[%d]", bus_high);
278
                else
279
                        return fprintf (f, "[%d:%d]", bus_high, bus_low);
280
        }
281
        return 0;
282
}
283
 
284
/* ********************************************************************** */
285
/* ?? looks like hangover from VHDL */
286
#if defined NEED_VLOG_TYPE
287
void decode_VLOG_type (FILE *f, vhdl_t *vhdl)
288
{
289
        /* avoid crashing on a null pointer */
290
        if (!vhdl)
291
                vhdl = default_vhdl_datatype;
292
        fprintf (f, "%s ", vhdl->basetype);
293
        decode_VLOG_bus (f, vhdl);
294
}
295
#endif
296
 
297
/* ********************************************************************** */
298
/* Certify specific stuff */
299
/* this copies declaration directives over */
300
void assign_declaration_directives (socket_t *skt, generic_info_t *list)
301
{
302
        while (list)
303
        {
304
                if (list->g_type == IS_DECLARATION_DIRECTIVE)
305
                        set_generic_value (&(skt->generics), list);
306
                if (list->g_type == IS_INSTANCE_DIRECTIVE)
307
                        set_generic_value (&(skt->generics), list);
308
                list = list->next;
309
        }
310
}
311
 
312
/* ********************************************************************** */
313
/* print out a VLOG component declaration */
314
 
315
void print_VLOG_component (FILE *f, socket_t *dev, int All)
316
{
317
        node_t *n;
318
        char printed = 0;
319
        char nam[MAXIDLEN], typ[MAXIDLEN];
320
        generic_info_t *g_list = dev->generics;
321
        make_VLOG_name (typ, check_null_str (dev->type));
322
 
323
        fprintf (f, "\nmodule  %s (\n", typ);
324
 
325
        /* sort the identifiers of the nodes */
326
        sort_nodes (dev, NO_EXTRACT_XY);
327
        n = dev->nodes;
328
        while (n)
329
        {
330
                /* print the pin ID if it is connected to a net and the net is routable */
331
                if (All || (n->net && n->net->how_routed != Not_Routable))
332
                {
333
                        char nam1[MAXIDLEN];
334
                        if (printed)
335
                                fprintf (f, ",\n");
336
                        printed = 1;
337
                        sprintf (nam1, "%s", check_null_str (n->identifier));
338
                        fprintf (f, "  %s", make_VLOG_name (nam, nam1));
339
                }
340
                n = n->sktnext; /* traverse to next pin on socket */
341
        };
342
        fprintf (f, " );\n\n");
343
        /* list any declaration directives */
344
        while (g_list)
345
        {
346
                if (g_list->g_type == IS_DECLARATION_DIRECTIVE)
347
                {
348
                        if (!g_list->expr || ISNULLSTR (g_list->expr->left.s))
349
                                fprintf (f, "/* synthesis %s */\n", g_list->name);
350
                        else
351
                                fprintf (
352
                                    f,
353
                                    "/* synthesis %s = %s*/\n",
354
                                    g_list->name,
355
                                    check_null_str (g_list->expr->left.s));
356
                }
357
                g_list = g_list->next;
358
        }
359
 
360
        n = dev->nodes;
361
 
362
        while (n)
363
        {
364
                if (dev->is_template || (n->net && n->net->how_routed != Not_Routable))
365
                {
366
                        fprintf (
367
                            f,
368
                            " %8s %s ",
369
                            decode_pin_VLOG[(int) n->pindir],
370
                            make_VLOG_name (nam, check_null_str (n->identifier)));
371
                        decode_VLOG_bus (f, n->vhdltype);
372
                        fprintf (f, ";\n");
373
                }
374
                n = n->sktnext; /* traverse to next pin on socket */
375
        };
376
        fprintf (f, "endmodule\n\n");
377
}
378
 
379
/* ********************************************************************** */
380
/* Printout an instance of a component */
381
/* ********************************************************************** */
382
void print_VLOG_instance (FILE *f, socket_t *dev, int All)
383
{
384
        node_t *n;
385
        int need_term = 0;
386
        char nam[MAXIDLEN], id[MAXIDLEN];
387
        generic_info_t *g_list = dev->generics;
388
        make_VLOG_name (nam, check_null_str (dev->type));
389
        make_VLOG_name (id, check_null_str (dev->identifier));
390
 
391
        fprintf (f, "\n\n/* Component instance */\n");
392
        fprintf (f, "%s %s ", nam, id);
393
 
394
        while (g_list)
395
        {
396
                if (g_list->g_type == IS_INSTANCE_DIRECTIVE)
397
                {
398
                        if (!g_list->expr || ISNULLSTR (g_list->expr->left.s))
399
                                fprintf (f, "/* synthesis %s */\n", g_list->name);
400
                        else
401
                                fprintf (
402
                                    f,
403
                                    "/* synthesis %s = %s*/\n",
404
                                    g_list->name,
405
                                    check_null_str (g_list->expr->left.s));
406
                }
407
                g_list = g_list->next;
408
        }
409
 
410
        fprintf (f, "   (\n");
411
 
412
        sort_nodes (dev, NO_EXTRACT_XY);
413
        n = dev->nodes;
414
 
415
        while (n)
416
        {
417
                char nam1[MAXIDLEN], nam2[MAXIDLEN];
418
                /* is there need to add a buffer signal prefix */
419
 
420
                if (n->net && n->net->how_routed != Not_Routable)
421
                {
422
                        if (need_term)
423
                                fprintf (f, ",\n");
424
                        else
425
                                fprintf (f, "\n");
426
                        need_term = 1;
427
 
428
                        if (n->net_assigned && n->in_use && !ISNULLSTR (n->identifier))
429
                        {
430
                                fprintf (
431
                                    f,
432
                                    "   .%s(%s",
433
                                    make_VLOG_name (nam1, check_null_str (n->identifier)),
434
                                    make_VLOG_name (
435
                                        nam2, check_null_str (n->net->name))); /* was
436
                                                                                  identifier */
437
                                decode_VLOG_bus (f, n->vhdltype);
438
                                fprintf (f, ")");
439
                        }
440
                        else
441
                        {
442
                                /* No assigned net : pin exists  */
443
                                fprintf (
444
                                    f,
445
                                    "   .%s()",
446
                                    make_VLOG_name (nam1, check_null_str (n->identifier)));
447
                        }
448
                }
449
                else
450
                {
451
                        if (n->net && n->net->how_routed != Not_Routable)
452
                        {
453
                                /* If we are printing comments then dont need a comma next time
454
                                 */
455
                                if (need_term)
456
                                        fprintf (f, ",\n");
457
                                else
458
                                        fprintf (f, "\n");
459
                                need_term = 1;
460
                                fprintf (
461
                                    f,
462
                                    "   .pin_%s()",
463
                                    make_VLOG_name (nam1, check_null_str (n->identifier)));
464
                        }
465
                }
466
                n = n->sktnext; /* traverse to next pin on socket */
467
        };
468
        fprintf (f, "\n   );\n\n");
469
}
470
 
471
/* ********************************************************************** */
472
 
473
void print_VLOG_sigs (FILE *f)
474
{
475
        net_t *net = named_list;
476
        int width = 0;
477
        char nam[MAXIDLEN], *sig_prefix;
478
        while (net)
479
        {
480
                if (net->needs_buff_sig)
481
                        sig_prefix = BUFPREFIX;
482
                else
483
                        sig_prefix = "";
484
 
485
                if ((net->how_routed != Not_Routable) &&
486
                    ((net->bundle_member) || ((net->inside_partition) && net->has_external)))
487
                { /* May 21 2001 only print nets that connect to 'external' tagged modules */
488
                        /* add to this those in a bundled connection */
489
                        width += fprintf (
490
                            f, " wire %s%s;", sig_prefix, make_VLOG_name (nam, net->name));
491
                        if (strcmp (nam, net->name) != 0) /* names changed by printout */
492
                                width += fprintf (f, "/* \"%s\" */", net->name);
493
                }
494
                else
495
                {
496
                        if (level & 1)
497
                        {
498
                                fprintf (
499
                                    f,
500
                                    "  /* wire %s%s; ",
501
                                    sig_prefix,
502
                                    make_VLOG_name (nam, net->name));
503
                                fprintf (f, " */");
504
                        }
505
                }
506
                if (level & 1)
507
                {
508
                        fprintf (
509
                            f,
510
                            " /* partition : %s %s %s %s %s*/\n",
511
                            net->inside_partition ? "used in," : "unused in,",
512
                            net->leaves_partition ? "leaves," : "buried,",
513
                            net->needs_buff_sig ? ", buffered," : "",
514
                            net->has_external ? "external skt" : "internal skt",
515
                            net->bundle_member ? "bundle member" : " not bundled");
516
                }
517
 
518
                if ((level & 1) || (width > MAXWIDTH))
519
                {
520
                        width = 0;
521
                        fprintf (f, "\n  ");
522
                }
523
 
524
                net = net->next;
525
        }
526
}
527
/* ********************************************************************** */
528
 
529
void print_VLOG_assignments (FILE *f)
530
{
531
        net_t *net = named_list;
532
        socket_t *socket = socket_head;
533
        fprintf (f, "/* Bundle signals */\n\n");
534
 
535
        while (socket)
536
        {
537
                node_t *nodes = socket->nodes;
538
                if (socket->highest_bundle &&
539
                    (socket->bundle_width > MINBUNDLE)) /* will not do assigns on small bundles
540
                                                         */
541
                        while (nodes)
542
                        {
543
                                /*      if (strcmp("X6",socket->identifier)==0)              */
544
                                /*        {                                                  */
545
                                /*        printf("-- X6 index = %d\n",nodes->bundle_index);  */
546
                                /*        }                                                  */
547
                                if (nodes->bundle_index >= 0)
548
                                {
549
                                        char nam[MAXIDLEN];
550
                                        net_t *net = nodes->net;
551
                                        make_VLOG_name (nam, net->name);
552
                                        fprintf (
553
                                            f,
554
                                            " assign %s[%d] = %s;\n",
555
                                            socket->identifier,
556
                                            nodes->bundle_index,
557
                                            nam);
558
                                }
559
                                nodes = nodes->sktnext;
560
                        }
561
                /*    else
562
                      fprintf(f,"-- %s;\n",
563
                               net->name);
564
                */
565
 
566
                socket = socket->next;
567
        }
568
        fprintf (f, "/* end bundle signals */ \n\n");
569
 
570
#if defined USE_PREV
571
        fprintf (f, "/* Bundle signals */\n\n");
572
 
573
        while (net)
574
        {
575
                if (net->bundle_parent)
576
                {
577
                        char nam[MAXIDLEN];
578
                        make_VLOG_name (nam, net->name);
579
                        fprintf (
580
                            f,
581
                            " assign %s[%d] = %s;\n",
582
                            net->bundle_parent->identifier,
583
                            net->bundle_index,
584
                            nam);
585
                }
586
                /*    else
587
                      fprintf(f,"-- %s;\n",
588
                               net->name);
589
                */
590
 
591
                net = net->next;
592
        }
593
        fprintf (f, "/* end bundle signals */ \n\n");
594
#endif
595
 
596
        net = named_list;
597
        fprintf (f, "/* Buffered signals */\n\n");
598
        while (net)
599
        {
600
                if (net->inside_partition && net->needs_buff_sig)
601
                {
602
                        char nam[MAXIDLEN];
603
                        make_VLOG_name (nam, net->name);
604
 
605
                        fprintf (f, " assign " BUFPREFIX "%s = %s;\n", nam, nam);
606
                }
607
                net = net->next;
608
        }
609
 
610
        fprintf (f, "/* end Buffered signals */ \n\n");
611
}
612
 
613
/* ********************************************************************** */
614
 
615
void print_VLOG_entity (FILE *f, char *entityname)
616
{
617
        net_t *net;
618
        int need_term = 0;
619
        int width = 0;
620
        socket_t *skt;
621
        char nam[MAXIDLEN];
622
 
623
        fprintf (f, "\nmodule %s ", entityname);
624
 
625
        fprintf (f, "(\n  ");
626
 
627
        skt = socket_head;
628
        /* bundles of pins are replaced by signals named the same as a socket which
629
           they are bundled through , unless the bundles are too small in which case they
630
           are replaced by separate wires */
631
        while (skt)
632
        {
633
                if (skt->highest_bundle)
634
                {
635
                        if (skt->bundle_width > MINBUNDLE)
636
                        {
637
                                if (need_term)
638
                                {
639
                                        width += fprintf (f, ", ");
640
                                        need_term = 0;
641
                                }
642
                                if (width > MAXWIDTH)
643
                                {
644
                                        width = 0;
645
                                        fprintf (f, "\n  ");
646
                                }
647
                                width += fprintf (f, "%s", skt->identifier);
648
                                need_term = 1;
649
                        }
650
                        else
651
                        /* if the 'bundle' has less than MINBUNDLE pins, */
652
                        /* list out all of the nets in turn as pins      */
653
                        {
654
                                node_t *node;
655
                                node = skt->nodes;
656
                                while (node)
657
                                {
658
                                        net = node->net;
659
                                        /*
660
                                            printf("node %s\n",node->identifier);
661
                                        */
662
                                        if (net && (net->how_routed != Not_Routable) &&
663
                                            net->bundle_member)
664
                                        {
665
                                                if (need_term)
666
                                                {
667
                                                        width += fprintf (f, ", ");
668
                                                        need_term = 0;
669
                                                }
670
                                                if (width > 60)
671
                                                {
672
                                                        width = 0;
673
                                                        fprintf (f, "\n  ");
674
                                                }
675
                                                width += fprintf (f, "%s", net->identifier);
676
                                                need_term = 1;
677
                                        }
678
                                        node = node->sktnext;
679
                                }
680
                        }
681
                }
682
 
683
                skt = skt->next;
684
        }
685
 
686
        net = named_list;
687
 
688
        while (net)
689
        {
690
                /* print out only unbundled nets as ports of the pcb */
691
                if (net->leaves_partition && !net->bundle_member)
692
                {
693
                        if (need_term)
694
                        {
695
                                width += fprintf (f, ", ");
696
                        }
697
                        if (width > MAXWIDTH)
698
                        {
699
                                width = 0;
700
                                fprintf (f, "\n  ");
701
                        }
702
                        width += fprintf (f, " %s", make_VLOG_name (nam, net->name));
703
                        /*        width+= decode_VLOG_bus(f,net->vhdltype); Not used in verilog
704
                         */
705
                        if (strcmp (nam, net->name) != 0) /* names changed by printout */
706
                                width += fprintf (f, " /* \"%s\" */", net->name);
707
 
708
                        need_term = 1;
709
                }
710
                net = net->next;
711
        }
712
        /* terminate port list */
713
        fprintf (f, ");\n");
714
 
715
        fprintf (f, "/* synthesis syn_partition = \"board\" */ \n\n");
716
 
717
        need_term = 0;
718
        skt = socket_head;
719
 
720
        /* now write out the verilog types of ll of the ports*/
721
 
722
        while (skt)
723
        {
724
                if (skt->highest_bundle)
725
                {
726
                        /* big bundles are listed as a single item */
727
                        if (skt->bundle_width > MINBUNDLE)
728
                        {
729
                                fprintf (
730
                                    f,
731
                                    "  inout [%d:%d] %s; // row(%d:%d) col(%d:%d) \n",
732
                                    skt->highest_bundle,
733
                                    skt->lowest_bundle,
734
                                    skt->identifier,
735
                                    skt->min_pin_row,
736
                                    skt->max_pin_row,
737
                                    skt->min_pin_col,
738
                                    skt->max_pin_col);
739
                        }
740
                        else
741
                        /* small bundles are enumerated as induvidual wires */
742
                        {
743
                                node_t *node;
744
                                node = skt->nodes;
745
                                while (node)
746
                                {
747
                                        net = node->net;
748
                                        /*
749
                                            printf("node %s\n",node->identifier);
750
                                        */
751
                                        if (net && net->bundle_member)
752
                                        {
753
                                                fprintf (
754
                                                    f, "  %s ", decode_pin_VLOG[net->ext_dir]);
755
                                                decode_VLOG_bus (f, net->vhdltype);
756
                                                fprintf (
757
                                                    f,
758
                                                    " %s;\n",
759
                                                    make_VLOG_name (nam, net->name));
760
                                        }
761
                                        node = node->sktnext;
762
                                }
763
                        }
764
                }
765
 
766
                skt = skt->next;
767
        }
768
 
769
        net = named_list;
770
 
771
        while (net)
772
        {
773
                char nam[MAXIDLEN];
774
                if (net->leaves_partition && !net->bundle_member)
775
                {
776
                        fprintf (f, "  %s ", decode_pin_VLOG[net->ext_dir]);
777
                        decode_VLOG_bus (f, net->vhdltype);
778
                        fprintf (f, " %s;\n", make_VLOG_name (nam, net->identifier));
779
                }
780
                net = net->next;
781
        }
782
        fprintf (f, "\n");
783
}
784
 
785
/* ********************************************************************** */
786
/* generate default VLOG Libraries */
787
/* ********************************************************************** */
788
void print_VLOG_libs (FILE *f)
789
{
790
        fprintf (f, "/* Default text */\n\n");
791
}
792
 
793
/* **********************************************************************
794
 * clear verilog 'type seen' flags (providing a single declaration for all
795
 * instances of a given type
796
 * **********************************************************************
797
 * Using this as a means to avoid duplicate components: only print those
798
 * not seen before */
799
 
800
void clr_type_seen (void)
801
{
802
        socket_t *skt;
803
        skt = template_head;
804
        while (skt)
805
        {
806
                skt->socket_type_seen = 0;
807
                skt = skt->next;
808
        }
809
}
810
/* **********************************************************************
811
 * set verilog 'type seen' flags  for all instances of a given type
812
 * ********************************************************************** */
813
void set_type_seen (char *type)
814
{
815
        socket_t *skt;
816
        skt = socket_head;
817
        while (skt)
818
        {
819
                if (strcmp (type, skt->type) == 0)
820
                        skt->socket_type_seen = 1;
821
                skt = skt->next;
822
        }
823
}
824
 
825
/* ********************************************************************** */
826
/* declare all used modules (once !!)  */
827
/* ********************************************************************** */
828
/* to do: fix up a generic giving an alternative verilog line for the
829
   FPGA declaration case eg 'include something.v
830
 
831
Need to
832
   bundle a socket then del external it for port bundling
833
 
834
*/
835
 
836
void print_VLOG_declarations (FILE *f, char *entityname)
837
{
838
        socket_t *skt;
839
        skt = socket_head;
840
        clr_type_seen ();
841
 
842
        skt = socket_head;
843
        /* list out templates for those sockets selected, and which have not been
844
           converted into a bundle */
845
        while (skt)
846
        {
847
                if (skt->is_external && skt->highest_bundle == 0)
848
                {
849
                        /* suppress printout of duplicate components .... */
850
                        if (skt->template_socket)
851
                        {
852
                                if (skt->template_socket->socket_type_seen == 0)
853
                                {
854
                                        if (!skt->is_FPGA)
855
                                        { /* only printout component decls for non-FPGA:
856
                                         Certify has its own private store of these
857
                                         declarations
858
                                         and it is fiddly to match these exactly. */
859
                                                fprintf (
860
                                                    f, "\n// defined by component template\n");
861
                                                print_VLOG_component (
862
                                                    f, skt->template_socket, 1);
863
                                        }
864
                                        else
865
                                        {
866
                                                generic_info_t *info = get_generic_ref (
867
                                                    &skt->generics, "fpga_file");
868
                                                fprintf (
869
                                                    f,
870
                                                    "\n/* socket '%s' is an FPGA: component "
871
                                                    "declaration skipped */\n",
872
                                                    skt->identifier);
873
                                                if (info && info->g_type == IS_ATTRIBUTE)
874
                                                {
875
                                                        fprintf (
876
                                                            f,
877
                                                            "/* replacement for declaration "
878
                                                            "*/\n%s\n",
879
                                                            info->expr->left.s
880
                                                                ? info->expr->left.s
881
                                                                : "");
882
                                                }
883
                                        }
884
                                        skt->template_socket->socket_type_seen = 1;
885
                                }
886
                        }
887
                        else
888
                        {
889
                                /* no components, use socket/entity as its own component */
890
                                if (!skt->is_FPGA)
891
                                {
892
                                        print_VLOG_component (f, skt, 1);
893
                                }
894
                                else
895
                                {
896
                                        generic_info_t *info =
897
                                            get_generic_ref (&skt->generics, "fpga_file");
898
                                        fprintf (
899
                                            f,
900
                                            "\n/* socket '%s' is an FPGA: socket declaration "
901
                                            "skipped */\n",
902
                                            skt->identifier);
903
                                        if (info && info->g_type == IS_ATTRIBUTE)
904
                                        {
905
                                                fprintf (
906
                                                    f,
907
                                                    "/* replacement for declaration */\n%s\n",
908
                                                    info->expr->left.s ? info->expr->left.s
909
                                                                       : "");
910
                                        }
911
                                }
912
                        }
913
                }
914
                skt = skt->next;
915
        }
916
}
917
 
918
/* ********************************************************************** */
919
/* generate a VLOG architecture  */
920
/* ********************************************************************** */
921
 
922
void print_VLOG_architecture (FILE *f, char *entityname)
923
{
924
        socket_t *skt;
925
        print_VLOG_entity (f, entityname);
926
 
927
        print_VLOG_sigs (f);
928
 
929
        skt = socket_head;
930
        while (skt)
931
        {
932
                if (skt->is_external && skt->highest_bundle == 0)
933
                        print_VLOG_instance (f, skt, 0);
934
                skt = skt->next;
935
        }
936
        print_VLOG_assignments (f);
937
        fprintf (f, "endmodule\n\n");
938
}
939
 
940
/* ********************************************************************** */
941
/* generate a VLOG file */
942
/* ********************************************************************** */
943
 
944
void produce_VLOG (FILE *f, char *entityname, char *template)
945
{
946
        char linebuff[256];
947
        int done_architecture = 0, done_declarations = 0;
948
        if (!template || !template[0])
949
        { /* check null pointer or empty string */
950
                fprintf (f, "// vertical verilog\n");
951
                print_VLOG_header (f, "WRITE VLOG");
952
                print_VLOG_declarations (f, entityname);
953
                print_VLOG_architecture (f, entityname);
954
                fprintf (f, "\n// vertical end;\n");
955
        }
956
        else
957
        { /* there is a template file */
958
                FILE *tp;
959
                tp = fopen (template, "r");
960
                if (tp)
961
                {
962
                        fprintf (f, "// vertical verilog\n");
963
                        print_VLOG_header (f, "WRITE VLOG");
964
                        fprintf (f, "/* Using template  '%s' */\n", template);
965
                        while (!feof (tp))
966
                        {
967
                                if (fgets (linebuff, 256, tp))
968
                                {
969
                                        if (strstr (linebuff, "$DECL$"))
970
                                        {
971
                                                print_VLOG_declarations (f, entityname);
972
                                                done_declarations++;
973
                                        }
974
 
975
                                        else if (strstr (linebuff, "$ARCH$"))
976
                                        {
977
                                                print_VLOG_architecture (f, entityname);
978
                                                done_architecture++;
979
                                        }
980
                                        else
981
                                                fprintf (f, "%s", linebuff); /* it already has
982
                                                                                a '\n' on the
983
                                                                                end */
984
                                }
985
                        }
986
                        fprintf (f, "\n// vertical end;\n");
987
                        fclose (tp);
988
                        if (done_declarations != 1)
989
                                Log (
990
                                    LOG_ERROR,
991
                                    "-- Error: %d  $DECL$ tags counted (need    1) in "
992
                                    "template '%s'\n",
993
                                    template);
994
                        if (done_architecture != 1)
995
                                Log (
996
                                    LOG_ERROR,
997
                                    "-- Error: %d  $ARCH$ tags counted (need    1) in "
998
                                    "template '%s'\n",
999
                                    template);
1000
                }
1001
                else
1002
                        Log (
1003
                            LOG_ERROR,
1004
                            "-- Error: Cannot open VLOG  template '%s'\n",
1005
                            template);
1006
        }
1007
}