Subversion Repositories Vertical

Rev

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