Subversion Repositories Vertical

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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. }
  1982.