Subversion Repositories Vertical

Rev

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

Rev Author Line No. Line
2 mjames 1
/* $Id: cmdexec1.c,v 1.1.1.1 2003/11/04 23:34:56 mjames Exp $
2
 *
3
 * $Log: cmdexec1.c,v $
4
 * Revision 1.1.1.1  2003/11/04 23:34:56  mjames
5
 * Imported into local repositrory
6
 *
7
 * Revision 1.31  2002/09/09 10:17:41  mjames
8
 * Altered search path description for HPUX
9
 *
10
 * Revision 1.30  2002/08/23 14:20:44  mjames
11
 * Updated comments on regular expressions.
12
 *
13
 * Revision 1.29  2002/08/19 14:30:04  mjames
14
 * Added the 'write UCF' command for
15
 * listing pin assignments in Xilinx UCF file format
16
 *
17
 * Revision 1.28  2002/08/06 12:52:07  mjames
18
 * Merge in from latest version
19
 *
20
 * Revision 1.31  2002/04/04 14:53:05  mjames
21
 * Added mentor board station reader to the portfolio
22
 *
23
 * Revision 1.30  2002/03/21 17:14:22  mjames
24
 * Added search path to vertical file opening for read
25
 *
26
 * Revision 1.29  2002/03/08 14:56:14  mjames
27
 * Edited all of the commands in the cmdexec1.c and cmdexec2.c files
28
 * so that they can be read by doc2.pl
29
 *
30
 * Revision 1.28  2002/03/08 11:54:38  mjames
31
 * Tagging for perl script to list commands out
32
 *
33
 * Revision 1.27  2002/01/15 12:37:47  mjames
34
 * now uses a function to set the debug level rather than global variable
35
 *
36
 * Revision 1.26  2001/12/24 21:14:00  mjames
37
 * Added header includes to get correct declarations for all functions
38
 * called from command handlers
39
 *
40
 * Revision 1.25  2001/12/24 20:08:38  mjames
41
 * Added more information about ensure template command to help message
42
 *
43
 * Revision 1.24  2001/12/20 13:54:19  mjames
44
 * Update version number to 15.1
45
 *
46
 * Revision 1.23  2001/12/13 22:13:22  mjames
47
 * Vertical now supports nested include database files
48
 * This allows wrappers around 'pure' VHDL or Verilog files
49
 *
50
 * Read command now initialises include stack correctly
51
 *
52
 * Revision 1.22  2001/11/19 10:41:05  mjames
53
 * Merge conflict resolution
54
 *
55
 * Revision 1.21  2001/11/09 22:14:45  mjames
56
 * Added in delete chip node connection command
57
 * In order to remove small number of chip pins in a large board
58
 * which have been damaged.
59
 *
60
 * Revision 1.20.2.1  2001/11/16 15:13:23  mjames
61
 * Included some more needed header files
62
 * Added extra documentation in auto generate -> HTML
63
 *
64
 * Revision 1.20  2001/10/31 22:20:00  mjames
65
 * Tidying up problematical comments caused by CVS
66
 * 'intelligent' comment guessing
67
 *
68
 * Revision 1.19  2001/10/23 21:28:51  mjames
69
 * Produce a list of diagnostic printouts enabled via the debug <n> command
70
 *
71
 * Revision 1.18  2001/10/11 16:10:18  mjames
72
 * Corrections to the SWAP command, and printout so that
73
 * WRITE net now outputs all chips in the design so that their generics
74
 * can be passed forward to the next phase.
75
 *
76
 * Revision 1.17  2001/10/02 20:55:18  mjames
77
 * Edited help files to try and get them more up to date.
78
 *
79
 * Revision 1.16  2001/09/21 14:13:52  mjames
80
 * Implemented Write Pin command
81
 *
82
 * Revision 1.15  2001/08/23 20:44:14  mjames
83
 * Corrected mistake in file name on write fit command.
84
 *
85
 * Revision 1.14  2001/07/09 15:09:36  mjames
86
 * Lists external sockets as components before using them
87
 *
88
 * Revision 1.13  2001/06/20 13:09:45  mjames
89
 * Took out 'from from' message.
90
 *
91
 * Revision 1.12  2001/06/19 05:24:34  mjames
92
 * Created a trap_fopen to overcome trying to write to read only files.
93
 * If this attempted in NT the file can be opened but not written to.
94
 *
95
 * Revision 1.11  2001/06/06 12:10:25  mjames
96
 * Move from HPUX
97
 *
98
 * Revision 1.10  2001/04/09 14:58:28  mjames
99
 * Added capability to delete generics from specific sockets.
100
 *
101
 * Revision 1.9  2001/04/04 22:12:31  mjames
102
 * Added some online documentation to the C program command handler
103
 * THis is scanned by a utility called 'doc' that currently creates
104
 * simple HTML from part formatted C comments
105
 *
106
 * Also working well on printing VERILOG
107
 *
108
 * still have problems with C comments and VERTICAL pragmas.
109
 *
110
 * Revision 1.8  2001/03/19 19:13:21  mjames
111
 * Tidied up a few commands
112
 *
113
 * Revision 1.7  2001/02/06 22:41:14  mjames
114
 * Added correct argument passing for 'read file comp_suffix arg0 arg1 arg2 ...
115
 *
116
 * Revision 1.6  2001/02/01 21:41:43  mjames
117
 * Made the code begin to compile without TCL/TK
118
 *
119
 * Revision 1.5  2001/01/26 21:50:09  mjames
120
 * Managed to get vertical non TCL to compile again
121
 *
122
 * Conversion to argv, argc[] mode of operation continues
123
 *
124
 * Revision 1.4  2001/01/04 21:26:54  mjames
125
 * Modifications to add in the TCL style
126
 * argument list to all of the functions
127
 * .
128
 *
129
 * Revision 1.3  2001/01/02 07:53:51  mjames
130
 * Made changes to allow for interface with TCL/Tk
131
 *
132
 * Revision 1.2  2000/10/21 20:41:29  mjames
133
 * Added the 'write flatten' command that only lists the wires
134
 * created by making jumpered connections rather than listing
135
 * the jumpers themselves
136
 *
137
 * Revision 1.1.1.1  2000/10/19 21:58:35  mjames
138
 * Mike put it here
139
 *
140
 *
141
 Removed RCS log information to reduce clutter
142
*****************************************************************************/
143
 
144
#include "bundle.h"
145
#include "chck_names.h"
146
#include "cmdexec.h"
147
#include "cmdlog.h"
148
#include "cmdparse.h"
149
#include "cmdutil.h"
150
#include "database.h"
151
#include "expression.h"
152
#include "ext_nets.h"
153
#include "generic.h"
154
#include "jumpering.h"
155
#include "partition.h"
156
#include "print_ports.h"
157
#include "print_quartus.h"
158
#include "print_ucf.h"
159
#include "print_vhdl.h"
160
#include "print_vlog.h"
161
#include "printout.h"
162
#include "rename.h"
163
#include "routing.h"
164
#include "statistics.h"
165
#include "template.h"
166
#include "unrouted.h"
167
#include "vertcl_main.h"
168
 
169
#include <stdio.h>
170
#include <stdlib.h>
171
#include <string.h>
172
 
173
 
174
tcl_mode_t Tcl_Mode;
175
 
176
/* make this a global */
177
Tcl_Interp *Tcl_interp;
178
 
179
#ident                                                                                        \
180
    "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/cmdexec1.c,v 1.1.1.1 2003/11/04 23:34:56 mjames Exp $"
181
/* Additional information for the user is provided in this section for inclusion in the
182
   HTML file
183
 
184
 
185
 
186
@title
187
Vertical application areas
188
@text
189
The following indices represent the commands that are likely to be useful for each
190
of the 'modes' of Vertical and its PCB translator family
191
@list_index
192
@end
193
*/
194
 
195
/*
196
@title
197
Vertical External PCB netlist translators
198
@index external
199
@end
200
*/
201
 
202
/*
203
@title
204
Vertical Pin assignment mode commands
205
@index vertical_pin
206
@end
207
*/
208
 
209
/*
210
@title
211
Vertical PCB merging commands
212
@index vertical_pcb
213
@end
214
*/
215
 
216
/*
217
@title
218
Vertical HDL handling commands
219
@index vertical_hdl
220
@end
221
*/
222
 
223
/*
224
@title
225
Vertical Regular expressions and commands that use them
226
@index regular_exp
227
@end
228
*/
229
 
230
/*
231
@title
232
Vertical search paths
233
@application vertical_pin
234
@application vertical_pcb
235
@application vertical_hdl
236
@text
237
As of version 15.5a, Vertical can now use search paths when opening scripts or database
238
files for reading. All file writes are in the current directory.
239
@break
240
For the PC the search path is :
241
@listing
242
.;c:/cygwin/usr/local/vert_files
243
@text
244
Or in english : look in the current directory '.' and then look in
245
'c:/cygwin/usr/local/vert_files'.
246
@break
247
For PC; filenames containing ':' or starting with either '/' or '.' are not searched down the
248
path,
249
 
250
@break
251
 
252
The path is in the environment variable called 'VERTICAL_PATH', which can either be
253
set in the shell (MSDOS or cygwin) which invokes vertical, or as a command from within
254
a Vertical script. e.g.
255
@listing
256
setenv VERTICAL_PATH "$(VERTICAL_PATH);/home/project/reference_data"
257
@text
258
This will make Vertical search in the usual places and then in the additional directory.
259
@break
260
For the HPUX port of Vertical the search path is
261
.;.caddata/vert_files
262
@text
263
For HPUX; filenames starting in '/' and '.' are not searched for down the path. These two
264
characters are normally used to specify a definite path, either relative to the current working
265
directory or absolute relative to the file system root.
266
@end
267
 
268
 
269
 
270
 
271
=======
272
   HTML file
273
@title
274
Vertical application areas
275
@text
276
The following indices represent the commands that are likely to be useful for each
277
of the 'modes' of Vertical and its PCB translator family
278
@listing
279
vertical_pin
280
vertical_pcb
281
vertical_hdl
282
@end
283
*/
284
 
285
/*
286
@title
287
Vertical Pin assignment mode commands
288
@index vertical_pin
289
@end
290
*/
291
 
292
/*
293
@title
294
Vertical PCB merging commands
295
@index vertical_pcb
296
@end
297
*/
298
 
299
/*
300
@title
301
Vertical HDL partitioning commands
302
@index vertical_hdl
303
@end
304
*/
305
 
306
/*
307
@title
308
Vertical script command notation: Command line and script files
309
@application vertical_pin
310
@application vertical_pcb
311
@application vertical_hdl
312
@text
313
Vertical uses its own 'shell' like command language. In this language, quoting a string
314
simply means that spaces appearing inside strings can be passed into Vertical as a single
315
argument. Normally spaces are used to delimit parameters in a command.
316
@break
317
When the command is listed out the following notation is used.
318
@text
319
If an item is given without angle ( '<' '>' ) brackets then the word is typed as is. e.g.
320
@listing
321
command
322
@break
323
If '<' '>' angle brackets are given then this an item such as a filename which is user defined.
324
e.g. Command followed
325
@listing
326
command <filename>
327
@break
328
If followed by an asterisk '*' it means in this context that more than one of these items
329
may be entered. It is not the same as a regular expression used within one of these items. e.g.
330
command followed by several items
331
@listing
332
command <item> *
333
@break
334
If '[' ']' square brackets are given then the item is optional. e.g. command with an optional
335
parameter
336
@listing
337
command [ <optional> ]
338
@text
339
More than one of these may appear at a time on the same item. e.g. Optional list of letters.
340
@end
341
 
342
@title
343
Vertical database file notation: Database files
344
@application vertical_pin
345
@application vertical_hdl
346
@application vertical_pcb
347
@text
348
Vertical handles several different database file formats. These are :
349
@listing
350
Altera .acf      : tagged as AHDL
351
Verilog          : tagged as VERILOG
352
VHDL             : tagged as VHDL
353
Vertical Native  : initial state and outside other tagged blocks
354
@text
355
They are all read in by a single database handler which can switch between different
356
languages on the fly.
357
@break
358
In all cases the Vertical parser begins expecting Vertical Native file format, and then
359
it is switched into other modes by the presence of tag  keywords
360
@break
361
These bracket the code. e.g.
362
@listing
363
VHDL -- this indicates following syntax.
364
  entity nine is
365
    (
366
    );
367
  end entity nine;
368
 
369
  architecture seven of nine is
370
-- vertical read_off
371
 this code will not be seen by vertical, as it has
372
 tags in the comments.
373
 
374
 DONT start comments with the word 'VERTICAL' as it is seen an
375
 an escape into vertical database language.
376
-- vertical read_on
377
 
378
  begin
379
 
380
  end;
381
END; -- this belongs to Vertical
382
@text
383
Because Vertical recognises the comments that are found in
384
all of the HDL's that it understands, it is possible to feed
385
a native HDL file in with Vertical tags in comments.
386
e.g.
387
 
388
 
389
 
390
 
391
@end
392
 
393
 
394
 
395
 
396
 
397
@title
398
regular expression: Information on wildcards in Vertical
399
@application vertical_pin
400
@application vertical_hdl
401
@application vertical_pcb
402
@text
403
The wildcards now used in several commands conform to standard regular expressions.
404
If no 'special' characters are given then patterns must match exactly, except that
405
the case of alphabetic characters is ignored.
406
@break
407
For instance: to select :
408
@listing
409
pattern   meaning
410
-------   -------
411
X2[1-7]   'X' or 'x', '2' and then digit '1' to '7'
412
.*        any char zero or more times (anything)
413
X[0-9]+   'X' or 'x', followed by one or more digits
414
 
415
(expr)    A pattern to be matched that can be used in a string replace.
416
          Each bracketed expression can be used in a replacement string
417
          &1 is the first pattern. &0 is the whole of the matched string.
418
 
419
@text
420
On cygwin and Unix 'man regex' will work to tell you more.
421
@break
422
The edit_pin ident command and edit_pin type
423
command documentation has more on regular expressions.
424
 
425
@break
426
Use '\' characters to escape special characters.
427
@end
428
 
429
 
430
 
431
*/
432
 
433
/************************************************************************/
434
/* Command handling code                                                */
435
/************************************************************************/
436
 
437
/*********************** Simple command calls ***************************/
438
/* BYE : Exit program
439
@title
440
bye, quit, exit
441
@application vertical_pcb
442
@application vertical_pin
443
@application vertical_hdl
444
@text
445
Leave program, closing files tidily.
446
@end
447
*/
448
int BYEHandler (ET_TCLARGS)
449
{
450
        CloseLog (); /* append summary and close the log file */
451
        Log (LOG_GENERAL, "#Goodbye for now\n");
452
        return (QUITCMD); /* try to leave cleanly */
453
}
454
 
455
/****************************************************************************/
456
/* external parser variables                                                */
457
extern int yydebug;
458
extern FILE *yyin;
459
extern int lineno;
460
extern int yy_nArgs;
461
extern char **yy_Args;
462
 
463
extern int inside_block;
464
 
465
/* debug level */
466
long level;
467
 
468
/******************** Setup YYDEBUG flag ***********************/
469
/*
470
@title
471
debug <debug_flags>
472
@application vertical_pcb
473
@application vertical_pin
474
@application vertical_hdl
475
@text
476
Internal debugging flags. Bit fields can be combined. In general issue debug
477
flag setting commands before issuing commands:
478
@break
479
Followed by the 'read' command:
480
@listing
481
For read command:
482
 
483
 
484
Bit 0    : The yydebug flag (see man yacc/lex for more info)
485
 
486
For template command
487
Bit 0    : Prints basic actions
488
Bit 1    : More detailed info
489
Bit 2    : Extremely detailed info.
490
 
491
For partition command
492
Bit 0    : Prints basic actions.
493
 
494
For route command
495
Bit 2    : Prints basic actions
496
Bit 3    : More detailed info
497
 
498
For jumper command
499
Bit 0    : Basic information
500
 
501
For set/del ext and set/del fpga commands
502
Bit 2    : Trace operations in detail
503
 
504
For equivalent pin operations (normally via netlist)
505
Bit 0    : Trace operations
506
 
507
For print vlog
508
Bit 0    : In Verilog file : indicate status for wires, list unused sigs as comments
509
 
510
For all file opening
511
Bit 4    : List files that Vertical attempts to open using its search path.
512
 
513
@end
514
*/
515
 
516
int DEBUGHandler (ET_TCLARGS)
517
{
518
        if (argc == 1)
519
        {
520
                level = atoi (argv[0]);
521
                set_debug_level (level); /* send info into DLL */
522
                yydebug = level & 1;
523
                Log (LOG_GENERAL, "# setting debug level to %d\n", level);
524
                return (TCL_OK);
525
        }
526
        else
527
                return (TCL_ERROR);
528
}
529
 
530
/******************** Read a data file ***********************/
531
/*
532
@title
533
read <filename> [<identifier_suffix> | "" ] [ <arg>* ]
534
@application vertical_pcb
535
@application vertical_pin
536
@application vertical_hdl
537
@text
538
Read a data file in to the internal database. If <suffix> is
539
given, the newly read socket and net identifiers are suffixed
540
with the suffix given. This is the means by which a single PCB
541
netlist file is given a unique identity. In this way the same
542
netlist may be repeated many times, but every object is given
543
an unique identifier.
544
In other words if the netlist is read in twice, once with the
545
suffix 'a' and once with the suffix 'b' then a socket 'U1' in
546
the netlist will become two sockets : 'U1a' and U1b' in the
547
combined netlist.
548
@break
549
String concatenation WARNING:
550
@break
551
If you have a set of sockets in the PCB netlist file  with
552
identifiers U1 to U 20 and you decide to suffix a new ACF file
553
being read with "0" then U1 in the new file will match U10 in
554
the old file and will 'vanish' or be confused with U10 in the
555
old file. The best way to avoid this problem is to
556
It is normal to use an underscore character as in "_" to
557
prefix the suffix to avoid this.
558
@break
559
In addition any arguments after the suffix field (which can be omitted if a "" null string is
560
given) can be used as macro variables $0, $1 and so on inside the database file.
561
e.g.
562
@listing
563
read conn.txt ""  x1_a x1_b
564
@text
565
Will, if the file conn.txt contains the following
566
@listing
567
JOINED_NETS
568
BEGIN
569
 
570
 
571
 
572
 
573
 JUMPER J_$0$1_3A  = ($0(3A );$1(16A); );
574
 JUMPER J_$0$1_4A  = ($0(4A );$1(15A); );
575
 JUMPER J_$0$1_5A  = ($0(5A );$1(14A); );
576
 JUMPER J_$0$1_6A  = ($0(6A );$1(13A); );
577
 
578
END;
579
@text
580
Be translated into
581
@listing
582
JOINED_NETS
583
BEGIN
584
 
585
 
586
 
587
 
588
 JUMPER J_x1_ax1_b_3A  = (x1_a(3A );x2_a(16A); );
589
 JUMPER J_x1_ax1_b_4A  = (x1_a(4A );x2_a(15A); );
590
 JUMPER J_x1_ax1_b_5A  = (x1_a(5A );x2_a(14A); );
591
 JUMPER J_x1_ax1_b_6A  = (x1_a(6A );x2_a(13A); );
592
 
593
END;
594
@text
595
If no arguments are given, then the argument list of the currently
596
executing script are used as $0, $1 and so on.
597
 
598
@end
599
*/
600
extern void tidy_lex (void);
601
 
602
extern int yyparse (void);
603
 
604
int READHandler (ET_TCLARGS)
605
{
606
        int rc = 0;
607
        int old_yy_nArgs;
608
        char **old_yy_Args;
609
 
610
#if defined DIAGNOSE
611
        {
612
                int i;
613
                printf ("local args\n");
614
 
615
                for (i = 0; i < argc; i++)
616
                        printf (
617
                            "[%d]=%s\n",
618
                            i,
619
                            argv[i] ? (argv[i][0] ? argv[i] : "\"\"") : "<null>");
620
                printf ("global args\n");
621
 
622
                for (i = 0; i < yy_nArgs; i++)
623
                        printf (
624
                            "[%d]=%s\n",
625
                            i,
626
                            yy_Args[i] ? (yy_Args[i][0] ? yy_Args[i] : "\"\"") : "<null>");
627
        }
628
#endif
629
        if (argc < 1)
630
                return (TCL_ERROR);
631
 
632
        Log (LOG_GENERAL, "# reading information from <%s>\n", argv[0]);
633
        mark_board_objects (); /* record some pointers - last object before rename */
634
        inside_block = 0;
635
 
636
        tidy_lex ();
637
 
638
        yyin = trap_fopen (argv[0], "r"); /* open text file for reading */
639
        if (!yyin)
640
        {
641
                Log (LOG_ERROR, "# Error opening file: <%s>\n", argv[0]);
642
                return (TCL_ERROR);
643
        }
644
        else
645
        {
646
                /* setup the argument lists for expansion :
647
                   either inherit from calling script (no args) or
648
                   copy from rest of command line. No need to make duplicates of
649
                   values as they cannot be changed within a 'read' operation
650
                   unlike 'do' which may call other command files with different arg.
651
                   lists.
652
                 */
653
                old_yy_nArgs = yy_nArgs;
654
                old_yy_Args = yy_Args;
655
                if (argc >= 3)
656
                {
657
                        yy_Args = argv + 2;
658
                        yy_nArgs = argc - 2;
659
                }
660
 
661
#if defined DIAGNOSE
662
 
663
                {
664
                        int i;
665
                        printf ("new global args\n");
666
 
667
                        for (i = 0; i < yy_nArgs; i++)
668
                                printf (
669
                                    "[%d]=%s\n",
670
                                    i,
671
                                    yy_Args[i] ? (yy_Args[i][0] ? yy_Args[i] : "\"\"")
672
                                               : "<null>");
673
                }
674
#endif
675
 
676
                lineno = 1;
677
                while (!feof (yyin) && !rc)
678
                {
679
                        if (yydebug)
680
                                Log (LOG_GENERAL, "Processing line %d\n", lineno);
681
                        rc = yyparse ();
682
                }
683
#if defined DIAGNOSE
684
                {
685
                        int i;
686
                        printf ("new2 global args\n");
687
 
688
                        for (i = 0; i < yy_nArgs; i++)
689
                                printf (
690
                                    "[%d]=%s\n",
691
                                    i,
692
                                    yy_Args[i] ? (yy_Args[i][0] ? yy_Args[i] : "\"\"")
693
                                               : "<null>");
694
                }
695
#endif
696
                fclose (yyin);
697
                yy_nArgs = old_yy_nArgs;
698
                yy_Args = old_yy_Args;
699
 
700
                /* added the concatenation of suffixes
701
                 * to the Names and Identifiers of objects *
702
                 * if there was a suffix and it is not null apply it */
703
                if (argc >= 2 && !ISNULLSTR (argv[1]))
704
                {
705
                        set_board_suffix (argv[1]);
706
                        Log (LOG_GENERAL, "# Object name/identifier suffix = '%s'\n", argv[1]);
707
                }
708
                need_validate_names = 1; /* tell validate_names there is some work to do */
709
 
710
                if (rc == 0)
711
                        return (TCL_OK);
712
                else
713
                        return (TCL_ERROR);
714
        }
715
}
716
 
717
/******************** Output an ACF file all pins connected to nets  ***********************/
718
/*
719
@title
720
write connected <filename>
721
@application vertical_pcb
722
@application vertical_pin
723
@text
724
Write out an 'Extended ACF' file for the entire netlist and
725
device and net assignments. If there are any sockets with
726
names assigned to the socket identifier (implying the socket
727
contains something important) then their entire pinout (without pin reservations) will be
728
written as part of the netlist. All connections made to external sockets will be listed.
729
@end
730
*/
731
int WriteConnectedHandler (ET_TCLARGS)
732
{
733
        FILE *ACFfile;
734
 
735
        if (argc < 1)
736
                return (TCL_ERROR);
737
        Log (LOG_GENERAL, "# producing an ACF file <%s>\n", argv[0]);
738
        ACFfile = trap_fopen (argv[0], "w"); /* open text file for reading */
739
        if (!ACFfile)
740
        {
741
                Log (LOG_ERROR, "# Error opening ACF output file: <%s>\n", argv[0]);
742
                return (TCL_ERROR);
743
        }
744
        else
745
        {
746
                create_unrouted_list ();
747
                print_header (ACFfile, TOOL_NAME ": WRITE CONNECTED");
748
                list_database (ACFfile, PRESERVE_JUMPERS);
749
                list_jumper (ACFfile);
750
                list_generic_values (ACFfile, &global_generics, 0);
751
 
752
                list_devices (
753
                    ACFfile,
754
                    PRINT_TYPE | PRINT_EXPAND_BUS | PRINT_NET_NAMES | PRINT_GENERIC |
755
                        PRINT_GROUP | PRINT_ROUTE_FLAGS | PRINT_EQUIVALENT_PINS);
756
                list_alias (ACFfile);
757
                print_pin_renames (ACFfile);
758
                fclose (ACFfile);
759
                return (TCL_OK);
760
        }
761
}
762
 
763
/******************** Output an ACF file ***********************/
764
/*
765
@title
766
write acf <filename>
767
@application vertical_pcb
768
@application vertical_pin
769
@text
770
Write out an 'Extended ACF' file for the entire netlist and
771
device and net assignments. If there are any sockets with
772
names assigned to the socket identifier (implying the socket
773
contains something important) then their pinout will be
774
written as part of the netlist. Connections to sockets without
775
names assigned are still written out.
776
@end
777
*/
778
int WriteAcfHandler (ET_TCLARGS)
779
{
780
        FILE *ACFfile;
781
 
782
        if (argc < 1)
783
                return (TCL_ERROR);
784
        Log (LOG_GENERAL, "# producing an ACF file <%s>\n", argv[0]);
785
        ACFfile = trap_fopen (argv[0], "w"); /* open text file for reading */
786
        if (!ACFfile)
787
        {
788
                Log (LOG_ERROR, "# Error opening ACF output file: <%s>\n", argv[0]);
789
                return (TCL_ERROR);
790
        }
791
        else
792
        {
793
                create_unrouted_list ();
794
                print_header (ACFfile, TOOL_NAME ": WRITE ACF");
795
                list_database (ACFfile, PRESERVE_JUMPERS);
796
                list_jumper (ACFfile);
797
                list_generic_values (ACFfile, &global_generics, 0);
798
 
799
                list_devices (
800
                    ACFfile,
801
                    PRINT_TYPE | PRINT_EXPAND_BUS | PRINT_GENERIC | PRINT_GROUP |
802
                        PRINT_ROUTE_FLAGS | PRINT_EQUIVALENT_PINS);
803
                list_alias (ACFfile);
804
                print_pin_renames (ACFfile);
805
                fclose (ACFfile);
806
                return (TCL_OK);
807
        }
808
}
809
/******************** Output an ACF, just net part file ***********************/
810
/*
811
@title
812
write net <filename>
813
@application vertical_pcb
814
@application vertical_pin
815
@text
816
Write out an 'Extended ACF' file for the entire netlist. In this case no socket
817
information is printed.
818
@end
819
*/
820
 
821
int WriteNetHandler (ET_TCLARGS)
822
{
823
        FILE *ACFfile;
824
 
825
        if (argc < 1)
826
                return (TCL_ERROR);
827
 
828
        Log (LOG_GENERAL, "# producing an ACF (net only) file <%s>\n", argv[0]);
829
        ACFfile = trap_fopen (argv[0], "w"); /* open text file for reading */
830
        if (!ACFfile)
831
        {
832
                Log (LOG_ERROR, "# Error opening ACF output file: <%s>\n", argv[0]);
833
                return (TCL_ERROR);
834
        }
835
        else
836
        {
837
                create_unrouted_list ();
838
                print_header (ACFfile, TOOL_NAME ": WRITE NET");
839
                list_database (ACFfile, PRESERVE_JUMPERS);
840
                list_jumper (ACFfile);
841
                list_devices (
842
                    ACFfile,
843
                    PRINT_TYPE | PRINT_GENERIC | PRINT_GROUP | PRINT_ROUTE_FLAGS |
844
                        PRINT_EQUIVALENT_PINS | NO_PRINT_PINS);
845
                fclose (ACFfile);
846
                return (TCL_OK);
847
        }
848
}
849
/******************** Write Flatten command ***********************/
850
/*
851
@title
852
write flatten <filename>
853
@application vertical_pcb
854
@application vertical_hdl
855
@text
856
Write out an 'Extended ACF' file for the entire netlist and
857
device and net assignments. If there are any sockets with
858
names assigned to the socket identifier (implying the socket
859
contains something important) then their pinout will be
860
written as part of the netlist. Connections to sockets without
861
names assigned are still written out.
862
@break
863
In addition, all jumpers are flattened, and the joined together
864
nets created by jumpers are written out as a single wire. This is used with the
865
equivalent pin connections on socket templates.
866
@end
867
*/
868
int WriteFlattenHandler (ET_TCLARGS)
869
{
870
        FILE *ACFfile;
871
 
872
        if (argc < 1)
873
                return (TCL_ERROR);
874
 
875
        Log (LOG_GENERAL, "# producing a flattened ACF file <%s>\n", argv[0]);
876
        ACFfile = trap_fopen (argv[0], "w"); /* open text file for reading */
877
        if (!ACFfile)
878
        {
879
                Log (LOG_ERROR, "# Error opening ACF output file: <%s>\n", argv[0]);
880
                return (TCL_ERROR);
881
        }
882
        else
883
        {
884
                create_unrouted_list ();
885
                print_header (ACFfile, TOOL_NAME ": WRITE FLATTEN");
886
                list_database (ACFfile, FLATTEN_JUMPERS);
887
                fclose (ACFfile);
888
                return (TCL_OK);
889
        }
890
}
891
/******************** Output an FRB file ***********************/
892
/*
893
@title
894
write pcb <filename>
895
@application vertical_pcb
896
@text
897
Write out a "neutral architecture file" PCB netlist file for
898
CadStar. This is hard to use properly, as Southampton Cadstar
899
users always seem to be coming up with different netlist
900
formats, and there are problems with library portability and
901
the unique and 'useful' way this has been setup at
902
Southampton.
903
@end
904
*/
905
int WriteFrbHandler (ET_TCLARGS)
906
{
907
        FILE *FRBfile;
908
        if (argc < 1)
909
                return (TCL_ERROR);
910
 
911
        Log (LOG_GENERAL, "# producing an FRB file <%s>\n", argv[0]);
912
        FRBfile = trap_fopen (argv[0], "w"); /* open text file for reading */
913
        if (!FRBfile)
914
        {
915
                Log (LOG_ERROR, "# Error opening FRB output file: <%s>\n", argv[0]);
916
                return (TCL_ERROR);
917
        }
918
        else
919
        {
920
                create_unrouted_list ();
921
                produce_frb (FRBfile);
922
                fclose (FRBfile);
923
                return (TCL_OK);
924
        }
925
}
926
/******************** Output a list of templates to a file ***********************/
927
/*
928
@title
929
write template <filename>
930
@application vertical_pin
931
@application vertical_hdl
932
@text
933
List out all of the socket templates (alternatively these are VHDL component declarations)
934
loaded into the VERTICAL database into a file,
935
which can be used to create a library of templates.
936
@end
937
*/
938
 
939
int WriteTemplateHandler (ET_TCLARGS)
940
{
941
        FILE *Templatefile;
942
 
943
        if (argc < 1)
944
                return (TCL_ERROR);
945
 
946
        Log (LOG_GENERAL, "# producing an Template file <%s>\n", argv[0]);
947
        Templatefile = trap_fopen (argv[0], "w"); /* open text file for reading */
948
        if (!Templatefile)
949
        {
950
                Log (LOG_ERROR, "# Error opening Template output file: <%s>\n", argv[0]);
951
                return (TCL_ERROR);
952
        }
953
        else
954
        {
955
                template_list_pins (Templatefile);
956
                fclose (Templatefile);
957
        }
958
        return (TCL_OK);
959
}
960
 
961
/************ Output a device by Name to file - expanding VHDL busses ********/
962
/*
963
@title
964
write fit <device> <filename>
965
@application vertical_pcb
966
@application vertical_pin
967
@application vertical_hdl
968
@text
969
Write out a device socket, and expand out busses, using the VHDL declarations
970
of the signals connected to produce the required number of pins. These databases
971
created can be used in the creation of an initial pin fit without the use of
972
an FPGA fitter.
973
@break
974
Partitioning use : If the 'chip' appears to have VHDL busses
975
rather than individual wires on some of its 'pins' then these
976
busses will be expanded into unique signal names. This process
977
is performed at the time of printout. A bus declared as
978
@listing
979
  fred : in STD_LOGIC (3 DOWNTO 0)
980
in the input acfp file will be printed out as
981
  fred_0 : INPUT_PIN :=  1_1 "STD_LOGIC"
982
  fred_1 : INPUT_PIN :=  1_2 "STD_LOGIC"
983
  fred_2 : INPUT_PIN :=  1_3 "STD_LOGIC"
984
  fred_3 : INPUT_PIN :=  1_4 "STD_LOGIC"
985
@end
986
*/
987
int WriteFitHandler (ET_TCLARGS)
988
{
989
        FILE *ACFfile;
990
        socket_t *skt;
991
 
992
        if (argc < 2)
993
                return (TCL_ERROR);
994
 
995
        skt = find_socket (Name, argv[0], Search, &socket_head);
996
 
997
        if (!skt)
998
        {
999
                Log (LOG_GENERAL, "# Cannot find socket name '%s'\n", argv[0]);
1000
                return (TCL_ERROR);
1001
        };
1002
        Log (LOG_GENERAL, "# producing ACF for socket name '%s' in <%s>\n", argv[0], argv[1]);
1003
        ACFfile = trap_fopen (argv[1], "w"); /* open text file for writing */
1004
        if (!ACFfile)
1005
        {
1006
                Log (LOG_ERROR, "# Error opening ACF output file: <%s>\n", argv[1]);
1007
                return (TCL_ERROR);
1008
        }
1009
        else
1010
        {
1011
                create_unrouted_list ();
1012
                print_header (ACFfile, TOOL_NAME ": WRITE FIT");
1013
                print_device (ACFfile, skt, PRINT_EXPAND_BUS); /* include pins not connected to
1014
                                                                  nets */
1015
                fclose (ACFfile);
1016
                return (TCL_OK);
1017
        }
1018
}
1019
 
1020
/******************** Output a device by ID to file ***********************/
1021
/*
1022
@title
1023
write identifier <chip_ident> <filename>
1024
@application vertical_pcb
1025
@application vertical_pin
1026
@application vertical_hdl
1027
@text
1028
Write out device info by ident  e.g. U1 or U2 . All pins that
1029
are known either on routed nets or unrouted nets will be
1030
listed. The names of the routed nets attached to the chip pins
1031
are given so that the user can detertmine which socket pins
1032
are usable for making connections to the socket. That is all
1033
of those that are not VCC or Ground for example.
1034
@break
1035
This format is exactly compatible with maxplus2 so it is used
1036
to produce the new pin assignment files for maxplus2
1037
It is also used to help with the creation of pin definition
1038
files for external connectors.
1039
@end
1040
*/
1041
int WriteIdHandler (ET_TCLARGS)
1042
{
1043
        FILE *ACFfile;
1044
        socket_t *skt;
1045
 
1046
        if (argc < 2)
1047
                return (TCL_ERROR);
1048
        skt = find_socket (Ident, argv[0], Search, &socket_head);
1049
 
1050
        if (!skt)
1051
        {
1052
                Log (LOG_GENERAL, "# Cannot find socket id '%s'\n", argv[0]);
1053
                return (TCL_ERROR);
1054
        };
1055
        Log (LOG_GENERAL, "# producing ACF for socket id '%s' in <%s>\n", argv[0], argv[1]);
1056
        ACFfile = trap_fopen (argv[1], "w"); /* open text file for writing */
1057
        if (!ACFfile)
1058
        {
1059
                Log (LOG_ERROR, "# Error opening ACF output file: <%s>\n", argv[1]);
1060
                return (TCL_ERROR);
1061
        }
1062
        else
1063
        {
1064
                create_unrouted_list ();
1065
                print_header (ACFfile, TOOL_NAME ": WRITE ID");
1066
                print_device (ACFfile, skt, PRINT_ALL | PRINT_USABLE); /* include pins not
1067
                                                                          connected to nets */
1068
                fclose (ACFfile);
1069
        }
1070
        return (TCL_OK);
1071
}
1072
 
1073
/******************** Output a device by name to file ***********************/
1074
/*
1075
@title
1076
write name <chip_name> <filename>
1077
@application vertical_pcb
1078
@application vertical_pin
1079
@application vertical_hdl
1080
@text
1081
Write out device info for the named device/socket  (with only
1082
pins that are used by routed nets). Tis is used for user
1083
documentation purposes and diagnostics, in separating out
1084
induvidual sockets from the netlist into separate files.
1085
@text
1086
@end
1087
*/
1088
int WriteNameHandler (ET_TCLARGS)
1089
{
1090
        FILE *ACFfile;
1091
        socket_t *skt;
1092
        if (argc < 2)
1093
                return (TCL_ERROR);
1094
 
1095
        skt = find_socket (Name, argv[0], Search, &socket_head);
1096
 
1097
        if (!skt)
1098
        {
1099
                Log (LOG_GENERAL, "# Cannot find socket name '%s'\n", argv[0]);
1100
                return (TCL_ERROR);
1101
        };
1102
        Log (LOG_GENERAL, "# producing ACF for socket name '%s' in <%s>\n", argv[0], argv[1]);
1103
        ACFfile = trap_fopen (argv[1], "w"); /* open text file for writing */
1104
        if (!ACFfile)
1105
        {
1106
                Log (LOG_ERROR, "# Error opening ACF output file: <%s>\n", argv[1]);
1107
                return (TCL_ERROR);
1108
        }
1109
        else
1110
        {
1111
                create_unrouted_list ();
1112
                print_header (ACFfile, TOOL_NAME " : WRITE NAME");
1113
                print_device (ACFfile, skt, 0); /* used pins only */
1114
                fclose (ACFfile);
1115
                return (TCL_OK);
1116
        };
1117
}
1118
/******************** Output a partition name to file ***********************/
1119
/*
1120
@title
1121
write VHDl <new_entityname> <filename> [ <template_file> ]
1122
@text
1123
Write out partition as VHDL, with the top level entity named
1124
as the new_entityname. If a template file name is given then
1125
the template file will be copied to filename, but where the
1126
string '$ENT$' appears in the template file, the entity will
1127
be inserted, and where the string '$ARCH$' appears in the
1128
template file, the architecture will be inserted. This allows
1129
for project specific libraries to be used and for specific
1130
header and footer information to be provided. e.g.
1131
@listing
1132
Example of a VHDL template file
1133
 
1134
-------------------------------
1135
-- Super dooper junk project --
1136
-- Default template file with--
1137
-- VERTICAL --------------------
1138
-------------------------------
1139
library ieee,proj_std;
1140
use ieee.std_logic_1164.all;
1141
use proj_std.dodgy_conversions.all;
1142
 
1143
-- Now an entity --
1144
$ENT$
1145
 
1146
library ieee,proj_std;
1147
use ieee.std_logic_1164.all;
1148
use proj_std.dodgy_conversions.all;
1149
 
1150
-- now an architecture --
1151
$ARCH$
1152
@text
1153
You will be warned if the template contains other than exactly
1154
one $ENT$ and $ARCH$ string.
1155
@end
1156
*/
1157
int WriteVHDLHandler (ET_TCLARGS)
1158
{
1159
        char *TemplateName;
1160
        FILE *VHDLfile;
1161
 
1162
        if (argc < 2)
1163
                return (TCL_ERROR);
1164
 
1165
        /* template name is optional */
1166
        TemplateName = NULL;
1167
        if (argc > 2)
1168
                TemplateName = argv[2];
1169
 
1170
        /* slip-up with a null pointer 17 Feb 2000  */
1171
        if (TemplateName && strcmp (TemplateName, argv[0]) == 0)
1172
        {
1173
                Log (
1174
                    LOG_ERROR,
1175
                    "# ERROR : VHDL template file name '%s' is the same as the template file "
1176
                    "name\n",
1177
                    argv[1]);
1178
                return (TCL_ERROR);
1179
        }
1180
 
1181
        Log (
1182
            LOG_GENERAL,
1183
            "# producing VHDL of partition for new entity name '%s' in <%s>\n",
1184
            argv[0],
1185
            argv[1]);
1186
        VHDLfile = trap_fopen (argv[1], "w"); /* open text file for writing */
1187
        if (!VHDLfile)
1188
        {
1189
                Log (LOG_ERROR, "# Error opening VHDL output file: <%s>\n", argv[1]);
1190
                return (TCL_ERROR);
1191
        }
1192
        else
1193
        { /* include a template if it exists */
1194
                create_unrouted_list ();
1195
                produce_VHDL (VHDLfile, argv[0], TemplateName);
1196
                fclose (VHDLfile);
1197
                return (TCL_OK);
1198
        };
1199
}
1200
/******************** Output a partition name to file ***********************/
1201
/*
1202
@title
1203
write VLOG <new_entityname> <filename>
1204
@text
1205
This is an experimental function used primarily with Certify.
1206
It writes out a board level netlist Verilog (.vb) file with
1207
only sockets that are set as external actually instanced. This
1208
removes unnecessary clutter from the design, and allows for
1209
the creation of large breadboards using VERTICAL to combine
1210
PCBs.
1211
@end
1212
*/
1213
int WriteVLOGHandler (ET_TCLARGS)
1214
{
1215
        char *TemplateName;
1216
 
1217
        FILE *VLOGfile;
1218
        if (argc < 2)
1219
                return (TCL_OK);
1220
 
1221
        /* template name is optional */
1222
        TemplateName = NULL;
1223
        if (argc > 2)
1224
                TemplateName = argv[2];
1225
 
1226
        /* slip-up with a null pointer 17 Feb 2000  */
1227
        if (TemplateName && strcmp (TemplateName, argv[1]) == 0)
1228
        {
1229
                Log (
1230
                    LOG_ERROR,
1231
                    "# ERROR : VLOG file name '%s' is the same as the template file name\n",
1232
                    argv[1]);
1233
                return (TCL_ERROR);
1234
        }
1235
 
1236
        Log (
1237
            LOG_GENERAL,
1238
            "# producing VLOG of partition for new entity name '%s' in <%s>\n",
1239
            argv[0],
1240
            argv[1]);
1241
        VLOGfile = trap_fopen (argv[1], "w"); /* open text file for writing */
1242
        if (!VLOGfile)
1243
        {
1244
                Log (LOG_ERROR, "# Error opening VLOG output file: <%s>\n", argv[1]);
1245
                return (TCL_ERROR);
1246
        }
1247
        else
1248
        { /* include a template if it exists */
1249
                create_unrouted_list ();
1250
                produce_VLOG (VLOGfile, argv[0], TemplateName);
1251
                fclose (VLOGfile);
1252
                return (TCL_OK);
1253
        };
1254
}
1255
/******************** Write Extern command ***********************/
1256
/*
1257
@title
1258
write EXTernal <filename>
1259
@text
1260
 
1261
Write  out  all sockets set as external to a file as  a  .acfp
1262
file.
1263
@break
1264
In addition a COMPONENTS block will be written
1265
@break
1266
This is intended to provide Vertical write extern
1267
with an explicit tie-up between the socket ID
1268
e.g. U1 and a device name in the socket e.g. BusChip or whatever. For example:
1269
@listing
1270
COMPONENTS
1271
  BEGIN
1272
  U1 : BusChip EPM7234 "" ;
1273
  END;
1274
@text
1275
@break
1276
In fact in many cases where write ext is used,  the contents of socket U1 will be known as
1277
device name U1.
1278
@break
1279
@listing
1280
COMPONENTS
1281
  BEGIN
1282
  U1 : U1 EPM7234 "" ;
1283
  END;
1284
@text
1285
Without this info, the tool cannot locate sockets by name using the chip identifier
1286
as ACF files do not contain the chip identifier, only the chip name.
1287
@break
1288
 
1289
 
1290
(see set external command)
1291
@end
1292
*/
1293
int WriteExternHandler (ET_TCLARGS)
1294
{
1295
        FILE *ACFfile;
1296
 
1297
        if (argc < 1)
1298
                return (TCL_ERROR);
1299
 
1300
        Log (LOG_GENERAL, "# producing an ACF file <%s>\n", argv[0]);
1301
        ACFfile = trap_fopen (argv[0], "w"); /* open text file for reading */
1302
        if (!ACFfile)
1303
        {
1304
                Log (LOG_ERROR, "# Error opening ACF output file: <%s>\n", argv[0]);
1305
                return (TCL_ERROR);
1306
        }
1307
        else
1308
        {
1309
                create_unrouted_list ();
1310
                print_header (ACFfile, TOOL_NAME ": WRITE EXTERN");
1311
                list_extern_sockets (ACFfile);
1312
                list_extern_devices (ACFfile);
1313
                fclose (ACFfile);
1314
                return (TCL_OK);
1315
        }
1316
}
1317
/******************** Output a device pin assignments as Xilinx Virtex UCF format
1318
 * ***********************/
1319
/*
1320
@title
1321
write UCF <chip_ident> <filename>
1322
@application vertical_pcb
1323
@application vertical_pin
1324
@application vertical_hdl
1325
@text
1326
Write out device info as a Xilinx Alliance (Virtex etc) UCF, naming socket
1327
by ident  e.g. U1 or U2 . All pins that
1328
are known either on routed nets or unrouted nets will be
1329
listed. The names of the routed nets attached to the chip pins
1330
are given so that the user can detertmine which socket pins
1331
are usable for making connections to the socket. That is all
1332
of those that are not VCC or Ground for example.
1333
@break
1334
This format is exactly compatible with Xilinx Alliance so it is used
1335
to produce the new pin assignment files for Xilinx Alliance
1336
@end
1337
*/
1338
int WriteUCFHandler (ET_TCLARGS)
1339
{
1340
        FILE *UCFfile;
1341
        socket_t *skt;
1342
 
1343
        if (argc < 2)
1344
                return (TCL_ERROR);
1345
        skt = find_socket (Ident, argv[0], Search, &socket_head);
1346
 
1347
        if (!skt)
1348
        {
1349
                Log (LOG_GENERAL, "# Cannot find socket id '%s'\n", argv[0]);
1350
                return (TCL_ERROR);
1351
        };
1352
        Log (LOG_GENERAL, "# producing UCF for socket id '%s' in <%s>\n", argv[0], argv[1]);
1353
        UCFfile = trap_fopen (argv[1], "w"); /* open text file for writing */
1354
        if (!UCFfile)
1355
        {
1356
                Log (LOG_ERROR, "# Error opening UCF output file: <%s>\n", argv[1]);
1357
                return (TCL_ERROR);
1358
        }
1359
        else
1360
        {
1361
                create_unrouted_list ();
1362
                print_UCF_instance (UCFfile, skt, PRINT_ALL | PRINT_USABLE); /* include pins
1363
                                                                                not connected
1364
                                                                                to nets */
1365
                fclose (UCFfile);
1366
                return (TCL_OK);
1367
        }
1368
}
1369
 
1370
/******************** Write Sockets command ***********************/
1371
/*
1372
@title
1373
write SOCkets <filename>
1374
@text
1375
Write  out  all sockets to a file as  a  .acfp
1376
file.
1377
@end
1378
*/
1379
int WriteSocketHandler (ET_TCLARGS)
1380
{
1381
        FILE *ACFfile;
1382
 
1383
        if (argc < 2)
1384
                return (TCL_ERROR);
1385
 
1386
        Log (LOG_GENERAL, "# producing an ACF file <%s>\n", argv[0]);
1387
        ACFfile = trap_fopen (argv[0], "w"); /* open text file for write*/
1388
        if (!ACFfile)
1389
        {
1390
                Log (LOG_ERROR, "# Error opening ACF output file: <%s>\n", argv[0]);
1391
                return (TCL_ERROR);
1392
        }
1393
        else
1394
        {
1395
                create_unrouted_list ();
1396
                print_header (ACFfile, TOOL_NAME ": WRITE SOCKETS");
1397
                list_components (ACFfile);
1398
                fclose (ACFfile);
1399
                return (TCL_OK);
1400
        }
1401
}
1402
 
1403
/******************** Output a device by name to file ***********************/
1404
/*
1405
@title
1406
write PAR_acf <new_entityname> <filename>
1407
@text
1408
Write out  partition  entity as Extended ACF so that it may be
1409
read in as a description of the ports of the top level of a
1410
partitiion, in conjunction with the  extended ACF files for
1411
the other partitions in the system.
1412
This then allows the connection together of all of the
1413
partitioned pieces of the design back into a new toplevel
1414
entitiy that may be simulated.
1415
@end
1416
*/
1417
int WriteParACFHandler (ET_TCLARGS)
1418
{
1419
        FILE *Parfile;
1420
        if (argc < 2)
1421
                return (TCL_ERROR);
1422
 
1423
        Log (
1424
            LOG_GENERAL,
1425
            "# producing Extended ACF of partition for new entity name '%s' in <%s>\n",
1426
            argv[0],
1427
            argv[1]);
1428
        Parfile = trap_fopen (argv[1], "w"); /* open text file for writing */
1429
        if (!Parfile)
1430
        {
1431
                Log (LOG_ERROR, "# Error opening ACF+ output file: <%s>\n", argv[1]);
1432
                return (TCL_ERROR);
1433
        }
1434
        else
1435
        {
1436
                create_unrouted_list ();
1437
                print_header (Parfile, TOOL_NAME " : WRITE PAR_ACF");
1438
                print_ACF_entity (Parfile, argv[0]);
1439
                fclose (Parfile);
1440
                return (TCL_OK);
1441
        };
1442
}
1443
 
1444
/******************** Output a device by name to Quartus pinfit file ***********************/
1445
/*
1446
@title
1447
write quartus <chip_name> <filename>
1448
@text
1449
Writes out a Quartus .pin pin assignment file with reserved pins and recommended tiedown pins.
1450
@end
1451
*/
1452
int WriteQuartusPinfitHandler (ET_TCLARGS)
1453
{
1454
        FILE *ACFfile;
1455
        socket_t *skt;
1456
        if (argc < 2)
1457
                return (TCL_ERROR);
1458
 
1459
        skt = find_socket (Name, argv[0], Search, &socket_head);
1460
 
1461
        if (!skt)
1462
        {
1463
                Log (LOG_GENERAL, "# Cannot find socket name '%s'\n", argv[0]);
1464
                return (TCL_ERROR);
1465
        };
1466
        Log (
1467
            LOG_GENERAL,
1468
            "# producing Quartus pinfit for socket name '%s' in <%s>\n",
1469
            argv[0],
1470
            argv[1]);
1471
        ACFfile = trap_fopen (argv[1], "w"); /* open text file for writing */
1472
        if (!ACFfile)
1473
        {
1474
                Log (LOG_ERROR, "# Error opening Quartus pinfit file: <%s>\n", argv[1]);
1475
                return (TCL_ERROR);
1476
        }
1477
        else
1478
        {
1479
                create_unrouted_list ();
1480
                print_header (ACFfile, TOOL_NAME " : WRITE QUARTUS");
1481
                print_quartus_pinfit (ACFfile, skt, 0); /* used pins only */
1482
                fclose (ACFfile);
1483
                return (TCL_OK);
1484
        };
1485
}
1486
 
1487
/******************** Write PinList *************************/
1488
/*
1489
@title
1490
write pinlist <socket_id*> <chip_id> [ <filename> ]
1491
@text
1492
Writes out a pinlist for the connections of socket(s) to an fpga. This is written to a file as
1493
HTML. It also writes the pin index created by the 'bundle' command if this has been used on a
1494
socket.
1495
@break
1496
This command is extremely useful for checking pin assignments
1497
@listing
1498
write fit x.*_a u1_a u1_a.html
1499
@text
1500
This lists all of the pinouts of connectors 'x' on board '_a' which are
1501
connected to 'u1_a'.
1502
@end
1503
*/
1504
 
1505
int WritePinlistHandler (ET_TCLARGS)
1506
{
1507
        FILE *ACFfile;
1508
        if (argc < 2)
1509
                return (TCL_ERROR);
1510
        if (argc > 2)
1511
                ACFfile = trap_fopen (argv[2], "w"); /* open text file for writing */
1512
        else
1513
                ACFfile = stdout;
1514
 
1515
        if (!ACFfile)
1516
        {
1517
                Log (LOG_ERROR, "# Error opening Pinlist file: <%s>\n", argv[2]);
1518
                return (TCL_ERROR);
1519
        }
1520
        else
1521
        {
1522
                list_intersection (ACFfile, argv[0], argv[1]);
1523
                if (ACFfile != stdout)
1524
                {
1525
                        fclose (ACFfile);
1526
                }
1527
        }
1528
        if (ACFfile != stdout)
1529
        {
1530
                fclose (ACFfile);
1531
        }
1532
        return TCL_OK;
1533
};
1534
 
1535
/******************** Write xxx Menu  ***********************/
1536
 
1537
CommandMenu const WriteMenu = {
1538
    {"acf",
1539
        3,
1540
        WriteAcfHandler, NULL, "Write out an 'Extended ACF' file", "<filename>", NULL},
1541
    {"connected",
1542
     3,
1543
     WriteConnectedHandler,
1544
     NULL,
1545
     "Write out an 'Extended ACF' file, with all connected pins",
1546
     "<filename>",
1547
     NULL},
1548
    {"net",
1549
     3,
1550
     WriteNetHandler,
1551
     NULL,
1552
     "Write out an 'Extended ACF' file, just the netlist part",
1553
     "<filename>",
1554
     NULL},
1555
    {"pcb",
1556
     3,
1557
     WriteFrbHandler,
1558
     NULL,
1559
     "Write out an 'FRB' PCB netlist file",
1560
     "<filename>",
1561
     NULL},
1562
    {"pinlist",
1563
     2,
1564
     WritePinlistHandler,
1565
     NULL,
1566
     "Write out Pin list for socket crossreferenced to FPGA",
1567
     "<socket ident> <fpga ident> <filename>",
1568
     NULL},
1569
 
1570
    {"identifier",
1571
     2,
1572
     WriteIdHandler,
1573
     NULL,
1574
     "Write out device info by ident. (with all pins)",
1575
     "<ident> <filename>",
1576
     NULL},
1577
    {"name",
1578
     3,
1579
     WriteNameHandler,
1580
     NULL,
1581
     "Write out device info by Name (with used pins)",
1582
     "<name> <filename>",
1583
     NULL},
1584
    {"fit",
1585
     3,
1586
     WriteFitHandler,
1587
     NULL,
1588
     "Write out device info by Name (with Expanded VHDL busses)",
1589
     "<name> <filename>",
1590
     NULL},
1591
    {"flatten",
1592
     3,
1593
     WriteFlattenHandler,
1594
     NULL,
1595
     "Write out Flattened (no jumpers) netlist",
1596
     "<filename>",
1597
     NULL},
1598
    {"extern",
1599
     3,
1600
     WriteExternHandler,
1601
     NULL,
1602
     "Write sockets with external connection flags set ",
1603
     "<filename>",
1604
     NULL},
1605
    {"quartus",
1606
     3,
1607
     WriteQuartusPinfitHandler,
1608
     NULL,
1609
     "Write Quartus pinfit file",
1610
     "<name> <filename>",
1611
     NULL},
1612
    {"sockets", 3, WriteSocketHandler, NULL, "Write socket list to file ", "<filename>", NULL},
1613
    {"template", 3, WriteTemplateHandler, NULL, "Write socket templates", "<filename>", NULL},
1614
    {"ucf",
1615
     3,
1616
     WriteUCFHandler,
1617
     NULL,
1618
     "Write Xilinx User configuration pin assignments",
1619
     "<ident> <filename>",
1620
     NULL},
1621
    {"vhdl",
1622
     3,
1623
     WriteVHDLHandler,
1624
     NULL,
1625
     "Write out partition as VHDL",
1626
     "<new_entityname> <filename> [<template VHDL>]",
1627
     NULL},
1628
    {"vlog",
1629
     3,
1630
     WriteVLOGHandler,
1631
     NULL,
1632
     "Write out partition as Verilog",
1633
     "<new_entityname> <filename> [<template Verilog>]",
1634
     NULL},
1635
    {"par_acf",
1636
     3,
1637
     WriteParACFHandler,
1638
     NULL,
1639
     "Write out partition entity as Extended ACF",
1640
     "<new_entityname> <filename>",
1641
     NULL},
1642
    {NULL, 0, NULL, NULL, NULL, NULL, NULL},
1643
 
1644
};
1645
 
1646
/*********************** List components Command  ***************************/
1647
/* this lists all of the sockets to standard output */
1648
/*
1649
@title
1650
list SOCkets
1651
@text
1652
List all of the known components in acfp form to standard output
1653
@end
1654
*/
1655
int ListSktHandler (ET_TCLARGS)
1656
{
1657
        list_components (stdout);
1658
        return (TCL_OK);
1659
}
1660
/*********************** List components Command  ***************************/
1661
/* this lists all of the sockets to standard output */
1662
/*
1663
@title
1664
list RENames
1665
@text
1666
List all of the pin renames in ACFP form to standard output
1667
@end
1668
*/
1669
 
1670
int ListRenamesHandler (ET_TCLARGS)
1671
{
1672
        print_pin_renames (stdout);
1673
        return (TCL_OK);
1674
}
1675
/*********************** List joins Command  ***************************/
1676
/* this lists all of the joins to standard output */
1677
/*
1678
@title
1679
list JOIn
1680
@text
1681
List all of the netlist joins (jumpers and aliases) in ACFP form to standard output
1682
@end
1683
*/
1684
 
1685
int ListJoinHandler (ET_TCLARGS)
1686
{
1687
        list_joined (stdout);
1688
        return (TCL_OK);
1689
}
1690
/*********************** List partition Command  ***************************/
1691
/* this lists all of the joins to standard output */
1692
/*
1693
@title
1694
list PARtition
1695
@text
1696
List out to standard output all of the entities currently selected to to combine
1697
in the top level entitiy when the partition is created
1698
@end
1699
*/
1700
 
1701
int ListPartHandler (ET_TCLARGS)
1702
{
1703
        list_partition (stdout);
1704
        return (TCL_OK);
1705
}
1706
 
1707
/*********************** List xref Command  ***************************/
1708
/* this lists all of the links from one socket to another
1709
   to standard output */
1710
/*
1711
@title
1712
list XREF [<chip_id>]
1713
@text
1714
List cross references between this socket and all other named
1715
sockets. The number of nets will be given, for each of the net
1716
lists used by VERTICAL.
1717
@listing
1718
EPLD tool : list xref b*
1719
-- Listing xref for socket names 'b*' --
1720
--  Cross reference for socket 'Bcu'
1721
Name            : Named&Used, Named, Routed,Unrouted
1722
             Bcu :    106,    16,  2419,     4
1723
         unused1 :      0,    78,     0,     0
1724
        test_par :     92,     0,  2312,     0
1725
         unused2 :      0,    78,     0,     0
1726
      bcu_x101_a :      2,     5,   526,     1
1727
 test_par_x111_a :      1,    60,   476,     0
1728
 test_par_x112_a :      0,    12,   473,     0
1729
  mips_connector :      0,     0,   471,     0
1730
  simm_connector :     16,     2,   478,     0
1731
    pi_bus_clock :      1,     0,    39,     0
1732
      mips_clock :      0,     0,    39,     0
1733
@text
1734
The example above shows the '*' wildcard used to indcate all
1735
named sockets with names beginning wiith 'b'. Name matching is
1736
case insensitive.
1737
@break
1738
If the template name given is blank then all sockets will be
1739
listed regardless of whether they are named, cross referenced
1740
to named sockets. A large amount of meaningless data will be
1741
obtained in this way.
1742
@break
1743
If the template name given is '*' then all named sockets are
1744
cross-referenced.
1745
@break
1746
The command may be used both in partitioning and in general
1747
PCB routing.
1748
@break
1749
Before partition, the cross reference  connection count is
1750
calculated via interpretation of the array range given in the
1751
component entity declaration  e.g. std_ulogic_vector ( 6
1752
downto 0 ) will be seen as 7 wires when doing a partition, and
1753
when the list xref command is given.
1754
@break
1755
After partition  and synthesis all signals become one physical
1756
wire or an array of discrete wires given as separate signals
1757
in any case.
1758
@end
1759
*/
1760
 
1761
int ListXrefHandler (ET_TCLARGS)
1762
{
1763
        char *SocketName;
1764
        SocketName = NULL; /* no names given, pass null pointer down */
1765
        if (argc > 0)
1766
                SocketName = argv[0];
1767
        count_paths (SocketName);
1768
        return (TCL_OK);
1769
}
1770
/*********************** List Templates Command  ***************************/
1771
/* this lists all of the available socket templates */
1772
/*
1773
@title
1774
list TEMplates
1775
@text
1776
List out all of the CHIP pin templates (or VHDL components) that are available (the
1777
device types)
1778
@end
1779
*/
1780
int ListTemplHandler (ET_TCLARGS)
1781
{
1782
        template_list ();
1783
        return (TCL_OK);
1784
}
1785
/*********************** List Generic Command  ***************************/
1786
/* this lists all of the global generic values */
1787
/*
1788
@title
1789
list GENerics
1790
@text
1791
List out all of the generics (variables)
1792
@end
1793
*/
1794
int ListGenericHandler (ET_TCLARGS)
1795
{
1796
        Log (LOG_GENERAL, "-- partition generics\n");
1797
        list_generic_values (stdout, &partition_generics, 0);
1798
        Log (LOG_GENERAL, "-- global generics\n");
1799
        list_generic_values (stdout, &global_generics, 0);
1800
        return (TCL_OK);
1801
}
1802
/*********************** List Unrouted Command  ***************************/
1803
/* this lists all of the unrouted nets */
1804
/*
1805
@title
1806
list UNRouted
1807
@text
1808
List out all of the currently unrouted nets. Use after ROUTE command to highlight those nets
1809
still not routed.
1810
@end
1811
*/
1812
int ListUnroutedHandler (ET_TCLARGS)
1813
{
1814
        if (unrouted_list)
1815
        {
1816
                fprintf (stdout, "-- Unrouted nets follow --\n");
1817
                list_nets (stdout, unrouted_list, 0);
1818
        }
1819
        else
1820
                fprintf (stdout, "-- Currently no unrouted nets --\n");
1821
 
1822
        return (TCL_OK);
1823
}
1824
 
1825
/*********************** List Net Command  ***************************/
1826
/* this lists all of the nodes on the named net */
1827
/*
1828
@title
1829
list NET <netname>
1830
@text
1831
Locates the named net, informs of which netlist it is found on, and then gives the node list of
1832
the net (devices visited).
1833
@end
1834
*/
1835
 
1836
int ListNetHandler (ET_TCLARGS)
1837
{
1838
        net_t *Net;
1839
        if (argc > 0)
1840
        {
1841
                Net = find_net (&named_list, Name, argv[0], Search);
1842
                if (Net)
1843
                        Log (LOG_GENERAL, "-- Net on named list\n");
1844
                else
1845
                {
1846
                        Net = find_net (&routed_list, Name, argv[0], Search);
1847
                        if (Net)
1848
                                Log (LOG_GENERAL, "-- Net on routed list\n");
1849
                        else
1850
                        {
1851
                                Net = find_net (&unrouted_list, Name, argv[0], Search);
1852
                                if (Net)
1853
                                        Log (LOG_GENERAL, "-- Net on unrouted list\n");
1854
                        }
1855
                }
1856
                if (Net)
1857
                        list_net_structure (stdout, Net, Net, 0, 0);
1858
        };
1859
        return (TCL_OK);
1860
}
1861
 
1862
/*********************** List Command  ***************************/
1863
 
1864
CommandMenu const ListMenu = {
1865
    {"sockets", 3, ListSktHandler, NULL, "List all known sockets", "", NULL},
1866
    {"joined", 3, ListJoinHandler, NULL, "List all joined nets", "", NULL},
1867
    {"xref", 3, ListXrefHandler, NULL, "List cross reference", "<socket_name>", NULL},
1868
 
1869
    {"partition", 3, ListPartHandler, NULL, "List current partition", "", NULL},
1870
    {"templates", 3, ListTemplHandler, NULL, "List IC templates", "", NULL},
1871
    {"generics", 3, ListGenericHandler, NULL, "List Global Generics", "", NULL},
1872
    {"renames", 3, ListRenamesHandler, NULL, "List Pin Renames", "", NULL},
1873
    {"unrouted", 3, ListUnroutedHandler, NULL, "List Unrouted nets ", "", NULL},
1874
    {"net", 3, ListNetHandler, NULL, "List nodes on net", "<netname>", NULL},
1875
 
1876
    {NULL, 0, NULL, NULL, NULL, NULL, NULL},
1877
};
1878
 
1879
/*********************** Connection handler  ***************************/
1880
/* connects the two sockets pin for pin */
1881
/*
1882
@title
1883
CONNect <socket_id1> <socket_id2>
1884
@text
1885
 
1886
This command provides a means for automatically jumpering
1887
together all pins on a pair of sockets. This connection is
1888
different to the jumper command.
1889
@break
1890
The connection command simply takes two sockets and connects
1891
up their pins in the routed metal netlist with the pins
1892
completely in order. This is what happens when two sockets are
1893
mated rather than a set of wirewrap jumpers being used to
1894
connect the sockets.
1895
@break
1896
In order for this to work, the sockets must have pin
1897
connections that can be found on the routed list : in other
1898
words, they are connected via metal connections to other
1899
sockets. Use of 'route' commands may be needed on some
1900
occasions in order to create the metal connection netlist from
1901
e.g. a list of sockets with assigned pins.
1902
@break
1903
Once the command is issued, the software takes each pin in
1904
turn on <socket_id1> and searches for the pin with the same
1905
identifier on <socket_id2>.
1906
@break
1907
If this pin is found then a jumper is created, even if the
1908
nets that the sockets are on are already jumpered to something
1909
else. This jumper created will have the identifier created by
1910
the concatenation of the socket identifiers and the pin
1911
identifiers : something like :
1912
cn_<socket_id1>_<socket_id2>_<pin_id>
1913
@break
1914
This command facilitates the connection together of different
1915
PCBs. If it is known that a connection cable (or X-PCB) is to
1916
be used which has a different connection pattern and/or
1917
connector type at each end of the cable, then it would be
1918
possible to manually create a netlist for the cable as though
1919
it were a PCB , with two sockets on it with appropriately
1920
connected via routed nets.
1921
@break
1922
Reading this PCB in (using the socket/net name suffixing
1923
feature of VERTICAL) and then issuing connection commands for
1924
each socket pair (one for each end of the new cable) will
1925
result in the desired set of jumpers being created.
1926
e.g.
1927
@break
1928
A script to be executed by VERTICAL
1929
@listing
1930
# Crossover script
1931
read conn_net _a
1932
read conn_net _b
1933
write acf cross_net0
1934
 
1935
# read in the connectors (have X1 and X2)
1936
read xc_pcb _a
1937
read xc_pcb _b
1938
# the main file has sockets ID1 and ID2 on it. Because they
1939
are read in
1940
# with name suffixes _a and _b they are distinct.
1941
# use the connector betweeen id1 on PCB _a and id1 on PCB _b
1942
con id1_a x1_a
1943
con id1_b x2_a
1944
# use the connector betweeen id2 on PCB _a and id2 on PCB _b
1945
con id2_a x1_b
1946
con id2_b x2_b
1947
 
1948
write acf cross_net
1949
Example of an acfp file describing a 4 way crossover (xc_pcb)
1950
COMPONENTS
1951
BEGIN
1952
  X1 : "test1" "PLUG4" "";
1953
  X2 : "test2" "PLUG4" "";
1954
END;
1955
 
1956
WIRED_NETS
1957
BEGIN
1958
CONNECTION "c1" "" CREATED_NET;
1959
X1(4); X2(1);
1960
 END_CONN;
1961
 CONNECTION "c2" "" CREATED_NET;
1962
X1(3); X2(2);
1963
 END_CONN;
1964
 CONNECTION "c3" "" CREATED_NET;
1965
X1(2); X2(3);
1966
 END_CONN;
1967
 CONNECTION "c4" "" CREATED_NET;
1968
X1(1); X2(4);
1969
 END_CONN;
1970
END;
1971
 
1972
@end
1973
*/
1974
 
1975
int ConnectionHandler (ET_TCLARGS)
1976
{
1977
        if (argc < 2)
1978
                return (TCL_ERROR);
1979
        create_all_jumpers (argv[0], argv[1]);
1980
        return (TCL_OK);
1981
}