/*
* $Id: printout.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $
*
* $Log: printout.c,v $
* Revision 1.1.1.1 2003/11/04 23:34:57 mjames
* Imported into local repositrory
*
* Revision 1.18 2002/09/27 22:32:07 MJAMES
* Added comments to make pin renames easier to find again
*
* Revision 1.17 2002/09/09 10:11:01 mjames
* Moved pin remapping function to pin ident editing function from
* sorting pin name routine.
*
* Revision 1.16 2002/08/06 12:52:33 mjames
* Merge in from latest version
*
* Revision 1.18 2002/08/06 08:51:49 mjames
* Removed mention of Altera from banner printed at top of files.
*
* Revision 1.17 2002/04/10 14:29:10 mjames
* Moved setting debug level to cmdutil.c
*
* Amended print external command to list all net names on socket pins
* whether routed or not.
*
* Revision 1.16 2002/03/08 11:49:00 mjames
* Corrected an error involving accessing strings via a null pointer when printing
* a list of sockets.
*
* Revision 1.15 2002/01/03 16:36:10 mjames
* Method of accessing Vertical version changed to avoid
* global variable
*
* Revision 1.14 2001/12/13 22:15:38 mjames
* Using #ident with header to identify file
*
* Revision 1.13 2001/11/30 22:16:14 mjames
* Printout of aliased templates has been corrected as the target alias
* type was not being printed.
*
* Revision 1.12 2001/11/01 11:02:55 mjames
* Removed unused variables.
* Allowed acf files to print device pinouts : this had failed because
* a && b was written where a & b was meant !
*
* Revision 1.11 2001/10/31 22:20:14 mjames
* Tidying up problematical comments caused by CVS
* 'intelligent' comment guessing
*
* Revision 1.10 2001/10/22 10:55:18 mjames
* Gives pin index min/max row/col as comments in component declarations
*
* Revision 1.9 2001/10/11 16:10:17 mjames
* Corrections to the SWAP command, and printout so that
* WRITE net now outputs all chips in the design so that their generics
* can be passed forward to the next phase.
*
* Revision 1.8 2001/10/10 20:18:22 mjames
* Added a vert_regcomp function to compile regular expressions
* with '^' (match start string) and '$' (match end string) bracketing
* this => wildcard must match entire string not just a part of it.
*
* Revision 1.7 2001/08/31 09:38:43 mjames
* Added a comment about the printing of equivalent pins being enabled by a flag
*
* Revision 1.6 2001/07/09 15:38:29 mjames
* Placed the version string in an independent file to save time on building
* all of the variants of Vertical
*
* Revision 1.5 2001/07/09 10:05:27 mjames
* Placed the version string in an independent file to save time on building
* all of the variants of Vertical
*
* Revision 1.4 2001/06/06 12:10:18 mjames
* Move from HPUX
*
* Revision 1.3 2000/11/29 21:51:19 mjames
* Fine tuning of software
*
* Revision 1.2 2000/10/21 20:41:29 mjames
* Added the 'write flatten' command that only lists the wires
* created by making jumpered connections rather than listing
* the jumpers themselves
*
* Revision 1.1.1.1 2000/10/19 21:58:39 mjames
* Mike put it here
*
*
* Revision 1.68 2000/10/04 10:37:08 10:37:08 mjames (Mike James)
* Modified for Vertical2 : support COMPONENTS and SIGNALS
*
* Revision 1.68 2000/10/04 10:37:08 10:37:08 mjames (Mike James)
* Part of Release PSAVAT01
*
* Revision 1.67 2000/10/02 11:04:18 11:04:18 mjames (Mike James)
* new_vhdl
*
* Revision 1.66 2000/09/27 14:42:19 14:42:19 mjames (Mike James)
* Part of Release Sep_27_ST_2000
*
* Revision 1.65 2000/09/27 14:27:57 14:27:57 mjames (Mike James)
* Made list renamed pins refer to device identifier.
*
* Revision 1.64 2000/09/27 10:58:07 10:58:07 mjames (Mike James)
* Started using g_class member of generic structure to control
* printing.
* ,.
*
* Revision 1.63 2000/09/21 10:15:49 10:15:49 mjames (Mike James)
* Part of Release Sep21Alpha
*
* Revision 1.62 2000/09/21 09:47:19 09:47:19 mjames (Mike James)
* Added code to deal with pin equivalents
*
* Revision 1.61 2000/08/25 09:57:15 09:57:15 mjames (Mike James)
* Part of Release Aug25_alpha
*
* Revision 1.60 2000/08/16 08:57:31 08:57:31 mjames (Mike James)
* Part of Release CD01_Aug2000
*
* Revision 1.59 2000/08/14 14:45:12 14:45:12 mjames (Mike James)
* Part of Release Aug_14_2000
*
* Revision 1.58 2000/08/14 14:43:29 14:43:29 mjames (Mike James)
* Added power pins
*
* Revision 1.57 2000/08/11 08:30:32 08:30:32 mjames (Mike James)
* Part of Release Aug_11_2000
*
* Revision 1.56 2000/08/09 10:31:47 10:31:47 mjames (Mike James)
* Part of Release Aug__9_2000
*
* Revision 1.55 2000/05/31 11:42:57 11:42:57 mjames (Mike James)
* Part of Release May_31_2000
*
* Revision 1.54 2000/05/08 17:01:38 17:01:38 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.53 2000/05/08 16:59:31 16:59:31 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.52 2000/05/08 16:57:08 16:57:08 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.51 2000/03/08 16:19:24 16:19:24 mjames (Mike James)
* New version including PC
*
* Revision 1.48 2000/02/18 15:45:44 15:45:44 mjames (Mike James)
* Amended to support PC
*
* Revision 1.47 2000/01/20 15:58:48 15:58:48 mjames (Mike James)
* Part of Release R22
*
* Revision 1.46 99/12/22 11:15:28 11:15:28 mjames (Mike James)
* Part of Release Dec_22_1999
*
* Revision 1.45 99/11/23 13:53:12 13:53:12 mjames (Mike James)
* Addedd Verilog support and removed VHDL functions to a separate
* file
*
* Revision 1.40 98/11/27 15:15:48 15:15:48 mjames (Mike James)
* Altered listing of jumpers
*
* Revision 1.39 98/11/16 13:18:36 13:18:36 mjames (Mike James)
*
* Revision 1.38 98/08/12 14:21:57 14:21:57 mjames (Mike James)
* COrrected VHDL printout
*
* Revision 1.37 98/07/14 13:25:38 13:25:38 mjames (Mike James)
* Altered device printout to meet new requirements
*
* Revision 1.36 98/06/15 14:19:01 14:19:01 mjames (Mike James)
* Added template printout functionality
*
* Revision 1.35 98/04/24 13:49:16 13:49:16 mjames (Mike James)
* Avoid priting 'generics' for chips without them
*
* Revision 1.34 98/03/16 11:37:55 11:37:55 mjames (Mike James)
* Added generics to printout listings
*
* Revision 1.33 98/02/11 11:27:01 11:27:01 mjames (Mike James)
* Checked in for version 6.2a
*
* Revision 1.32 98/01/13 11:33:41 11:33:41 mjames (Mike James)
* Added the bility to use a VHDL template file
* containing $ENT$ and $ARCH$ in the position where one
* wants the entity and architecture to be given.
*
* Revision 1.31 97/04/23 08:43:21 08:43:21 mjames (Mike James)
* CHecked in for release rel23041997
*
* Revision 1.30 96/12/23 15:19:14 15:19:14 mjames (Mike James)
* Altered headline for UMA email address
*
* Revision 1.29 96/12/23 15:12:52 15:12:52 mjames (Mike James)
* Fixing printout routines to work with templates
* (somewhat unecessary as they are on a different linked list
* to the sockets which was causing problems until I saw
* the mistake.
*
* Revision 1.28 96/12/23 10:23:33 10:23:33 mjames (Mike James)
* Altered to make it sort the results
* of listing COMPONENTS and CHIP pins.
* /
*
* Revision 1.27 96/12/13 08:43:06 08:43:06 mjames (Mike James)
* Update to v5.1, added Write ID , exact routing
*
* Revision 1.26 96/08/06 13:37:05 13:37:05 mjames (Mike James)
* Added FIX_LOCATION pin attribute to netlist
*
* Revision 1.25 96/07/19 14:38:39 14:38:39 mjames (Mike James)
* Update to give to PRL
*
* Revision 1.24 1996/07/12 15:52:12 mjames
* Sorted out things like Alias and Jumpers
* Work Correctly
* Print COrrectly
*
* Revision 1.23 96/07/09 15:53:39 15:53:39 mjames (Mike James)
* Altered aliasing to make it hierarchical, also for jumpering
*
* Revision 1.22 96/06/17 11:02:24 11:02:24 mjames (Mike James)
* Altered the printing of JUMPERED and ALIASED nets
* ,
*
* Revision 1.21 96/06/11 14:16:48 14:16:48 mjames (Mike James)
* Removed a spurios printf.
*
* Revision 1.20 96/06/11 14:11:22 14:11:22 mjames (Mike James)
* Added hierarchical jumpering
*
* Revision 1.19 96/06/10 13:26:00 13:26:00 mjames (Mike James)
* Checkin before altering joined/subnet behaviour
*
* Revision 1.18 96/06/04 11:53:11 11:53:11 mjames (Mike James)
* Added the ability to jumper nets by reference to a node on the nets
*
* Revision 1.17 96/05/21 14:13:53 14:13:53 mjames (Mike James)
* Altered printout decode_pin[] array as I have fixed buffer_pins
* so that they are beginning to work.
*
* Revision 1.16 96/04/26 16:02:23 16:02:23 mjames (Mike James)
* Altered inside/outside determination of signal directions
*
* Revision 1.15 96/04/15 14:19:33 14:19:33 mjames (Mike James)
* Checkin before datatype printing
* modifications
*
* Revision 1.14 96/03/29 14:46:30 14:46:30 mjames (Mike James)
* Added VHDL netlist writing to the capabilities of ACFREAD
*
* Revision 1.12 96/03/19 08:51:43 08:51:43 mjames (Mike James)
* Corrected bug with zero length nets crashing WRITE PCB
*
* Revision 1.8 96/03/13 15:36:10 15:36:10 mjames (Mike James)
* Altered the how_routed field to be used to indicate the routing algorithm used
* to route this net.
*
* Revision 1.7 96/02/13 09:13:27 09:13:27 mjames (Mike James)
* Updated to be version 2.0 with net joining
*
* Revision 1.6 96/02/09 10:50:21 10:50:21 mjames (Mike James)
* Added different behaviour for 'write id' and 'write name'
* 'write id' now writes all pins including unused ones
* 'write name' only writes used pins in the ACF file
*
* Revision 1.5 96/02/08 15:28:28 15:28:28 mjames (Mike James)
* First release
*
* Revision 1.4 96/02/07 16:01:32 16:01:32 mjames (Mike James)
* Added correct RCS header
*
* Revision 1.3 96/02/07 15:50:42 15:50:42 mjames (Mike James)
* Added RCS ident message
*
* Revision 1.2 96/02/07 11:04:19 11:04:19 mjames (Mike James)
* Checkin before adding new command parsing to program
*
* Revision 1.1 96/01/10 13:13:51 13:13:51 mjames (Mike James)
* Initial revision
*
*/
#include "printout.h"
#include "cmdlog.h"
#include "cmdparse.h"
#include "database.h"
#include "equivalent.h"
#include "expression.h"
#include "generic.h"
#include "print_vhdl.h"
#include "print_vlog.h"
#include "sorting.h"
#include "version.h"
#include "vertcl_main.h"
#include <ctype.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ident \
"@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/printout.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $"
/* decoding pin direction in ACF form */
/* see pindir_t in database.h */
static char *decode_pin[] = {"NONE",
"INPUT_PIN",
"OUTPUT_PIN",
"output_pin", /* buffer is a sort of Output pin (lower case is for
info only )*/
"BIDIR_PIN ",
"CONFIG_PIN",
"POWER_PIN"};
/* returns a valid pointer to a null string */
char *check_null_str (char *s)
{ /* using shortcircuit evaluation rules here */
if (!s
|| s
[0] == 0 || strcmp (s
, nullstr
) == 0)
return (nullstr);
else
return (s);
}
/* ********************************************************************** */
/* this prints out the contents of the working database */
/* prints a single net as a connection */
/* subnets are printed as having the how_routed field of their
parent, because this is the how_routed value that is indicated
by the routing */
void list_net_nodes (FILE *f, net_t *cnet, net_t *root_net)
{
noderef_t *bnode;
node_t *cnode;
int wrapc;
if (!cnet)
return;
f,
" CONNECTION \"%s\" \"%s\" %s; -- %d nodes\n ",
cnet->identifier,
check_null_str (root_net->name),
decode_how_routed[root_net->how_routed],
cnet->nodecount);
f,
"-- partition port=%d in=%d need_buff=%d\n",
cnet->leaves_partition,
cnet->inside_partition,
cnet->needs_buff_sig);
if (cnet->vhdltype)
{
print_range_expression (f, cnet->vhdltype->expr, NO_RECURSE);
}
if (cnet->type_defined)
fprintf (f
, "-- net type defined\n");
bnode = cnet->nodes;
wrapc = 0;
while (bnode)
{
cnode = bnode->node;
fprintf (f
, " %s(%s)", cnode
->socket
->identifier
, cnode
->identifier
);
/* printout if any lines have fix_location flags set */
if (cnode->fix_location)
{
wrapc += 2; /* cant get as much on this line */
}
if (cnode->fixed_pin)
{
wrapc += 2; /* cant get as much on this line */
fprintf (f
, " %s", decode_pin
[cnode
->pindir
]);
}
if (cnode->pin_group)
{
wrapc += 2; /* cant get as much on this line */
fprintf (f
, " (%d)", cnode
->pin_group
);
}
wrapc++;
if (wrapc >= 8)
{
wrapc = 0;
}
bnode = bnode->next;
};
if (wrapc)
}
/* ********************************************************************** */
void list_net_structure (
FILE *f, net_t *cnet, net_t *root_net, int alias_depth, int flatten_jumpers)
{
net_t *subnet;
subnet = cnet->subnets;
if (cnet == root_net)
if (cnet->how_joined == Jumpered && subnet)
{
f,
"-- Jumpered Connections to '%s' name '%s' found here --\n",
cnet->identifier,
cnet->name);
if (flatten_jumpers == FLATTEN_JUMPERS)
list_net_nodes (f, cnet, root_net);
else
while (subnet)
{
list_net_structure (
f, subnet, root_net, 0, flatten_jumpers); /* depth = 0, not
aliased */
subnet = subnet->joined_nets;
}
}
else if (cnet->how_joined == Aliased && subnet)
{
fprintf (f
, "-- Net nodes of aliased list here \n");
list_net_nodes (f, cnet, root_net);
f,
"-- %*s '%s' (name %s) created by Alias of --\n",
alias_depth,
"",
cnet->identifier,
cnet->name);
while (subnet)
{
fprintf (f
, "-- %*s '%s' -- \n", alias_depth
, "", subnet
->identifier
);
list_net_structure (
f, subnet, root_net, alias_depth + 1, flatten_jumpers);
subnet = subnet->joined_nets;
}
}
else if (alias_depth == 0)
list_net_nodes (f, cnet, root_net);
}
/* ********************************************************************** */
/* lists all the connections on the board */
void list_nets (FILE *f, net_t *cnet, int flatten_jumpers)
{
while (cnet)
{
list_net_structure (f, cnet, cnet, 0, flatten_jumpers);
cnet = cnet->next;
}
}
/* ********************************************************************** */
static void list_join (FILE *f, char *typ, net_t *cnet)
{
int wrapc = 1;
/* printf("List join %s , cnet = %p, join_parent = %p , join_parent->id =%p\n",
typ,cnet,cnet->join_parent,cnet->join_parent->identifier); */
fprintf (f
, " %s %s = (", typ
, cnet
->join_parent
->identifier
);
while (cnet)
{
if (cnet->external_node)
f,
"%s(%s); ",
cnet->external_node->socket->identifier,
cnet->external_node->identifier);
else
fprintf (f
, "%s; ", cnet
->identifier
);
wrapc++;
if (wrapc == 8)
{
wrapc = 0;
}
cnet = cnet->joined_nets;
}
}
/* ********************************************************************** */
/* we are now one level down so it must be a join of some sort
therefore join_parent is now valid */
static void list_subnets (FILE *f, net_t *cnet, JoinMode_t join)
{
net_t *tnet = cnet;
char *nettype;
net_t *topname;
while (tnet)
{
if (tnet->subnets)
list_subnets (f, tnet->subnets, join);
tnet = tnet->joined_nets;
}
/* if we are interested in aliases, print these */
/* Or if we are interested in joins print these */
/* printf("id %s join_parent %p howjoin %d\n",
cnet->identifier,cnet->join_parent,cnet->how_joined); */
if (cnet->join_parent->how_joined == join)
{
switch (join)
{
case Aliased:
nettype = "ALIAS";
break;
case Jumpered:
nettype = "JUMPER";
break;
default:
nettype = "??";
break;
};
list_join (f, nettype, cnet);
topname = cnet;
/* ascend jumper hierarchy to get the real name */
while (topname->join_parent && ISNULLSTR (topname->name))
topname = topname->join_parent;
if (join != Aliased && !ISNULLSTR (topname->name))
fprintf (f
, " -- signal '%s' \n", topname
->name
);
else
};
}
/* ********************************************************************** */
/* this lists all joined nets. it is recursive. Any subnets will be explored
before printing out the joins for this net if any are presaent */
static void list_joined_nets (FILE *f, net_t *cnet)
{
if (!cnet)
return;
while (cnet)
{
/* if there are any subnets here, do the recursion on them */
/* printf("cnet = %p, subnets= %p \n",cnet,cnet->subnets); */
if (cnet->subnets)
{
list_subnets (f, cnet->subnets, Jumpered);
}
if (cnet->vhdl_connect_net)
{
f,
" VHDL_CONN %s <= %s;\n",
cnet->name,
cnet->vhdl_connect_net->name);
}
cnet = cnet->next;
}
}
/************************************************************************/
static void list_routed_aliased_nets (FILE *f, net_t *cnet)
{
if (!cnet)
return;
while (cnet)
{
net_t *unrouted = cnet->unrouted_reference;
/* if there are any subnets here, do the recursion on them */
/* this will find out aliases if they exist */
if (unrouted && unrouted->subnets)
list_subnets (f, unrouted->subnets, Aliased);
cnet = cnet->next;
}
}
/************************************************************************/
static void list_aliased_nets (FILE *f, net_t *cnet)
{
if (!cnet)
return;
while (cnet)
{
/* if there are any subnets here, do the recursion on them */
/* printf("cnet = %p, subnets= %p \n",cnet,cnet->subnets); */
if (cnet->subnets)
list_subnets (f, cnet->subnets, Aliased);
cnet = cnet->next;
}
}
/************************************************************************/
void list_components (FILE *f)
{
socket_t *cskt = sort_sockets (&socket_head);
fprintf (f
, "COMPONENTS\nBEGIN\n");
while (cskt)
{
if (cskt->is_template)
fprintf (f
, "-- %s : Socket Template\n", cskt
->type
);
else
f,
" %s : \"%s\" \"%s\" \"%s\"; -- %s\n",
cskt->identifier,
check_null_str (cskt->name),
check_null_str (cskt->type),
check_null_str (cskt->value),
cskt->is_external ? "External" : "Internal");
cskt = cskt->next;
};
}
/***********************************************************************************/
/* only list device info for those sockets which have "external" flags set */
/*
This is intended to provide Vertical write extern
with an explicit tie-up between the socket ID
e.g. U1 and a device name in the socket e.g. BusChip or whatever. In fact in this
context the contents of socket U1 will be known as device name U1.
Without this info, the tool cannot locate sockets by name using the chip identifier
as ACF files do not contain the chip identifier, only the chip name.
*/
void list_extern_sockets (FILE *f)
{
socket_t *cskt = sort_sockets (&socket_head);
char *name;
fprintf (f
, "COMPONENTS\nBEGIN\n");
while (cskt)
{
if (cskt->is_external)
{
/* force the device to have an identifier if it does not have one */
name = cskt->name;
if (ISNULLSTR (name))
name = cskt->identifier;
f,
" %s : \"%s\" \"%s\" \"%s\";\n",
cskt->identifier,
name,
check_null_str (cskt->type),
check_null_str (cskt->value));
}
cskt = cskt->next;
};
}
/************************************************************************/
void list_database (FILE *f, int flatten_jumpers)
{
list_components (f);
fprintf (f
, "WIRED_NETS\nBEGIN\n");
fprintf (f
, "-- Routed & Named nets follow --\n\nNAMED\n\n");
list_nets (f, named_list, flatten_jumpers);
fprintf (f
, "-- Routed & unused nets follow --\n\nROUTED\n\n");
list_nets (f, routed_list, flatten_jumpers);
fprintf (f
, "-- Unrouted nets follow --\n\nUNROUTED\n\n");
list_nets (f, unrouted_list, flatten_jumpers);
}
/************************************************************************/
void list_jumper (FILE *f)
{
fprintf (f
, "-- Jumper list here --\n");
fprintf (f
, "JOINED_NETS\nBEGIN\n");
list_joined_nets (f, named_list);
list_joined_nets (f, routed_list);
}
/************************************************************************/
void list_alias (FILE *f)
{
fprintf (f
, "-- Alias list here --\n");
fprintf (f
, "JOINED_NETS\nBEGIN\n");
list_routed_aliased_nets (f, named_list);
list_routed_aliased_nets (f, routed_list);
list_aliased_nets (f, unrouted_list);
}
/************************************************************************/
void list_joined (FILE *f)
{
/* and now the joined nets */
fprintf (f
, "JOINED_NETS\nBEGIN\n");
fprintf (f
, "-- Jumper list here --\n");
list_joined_nets (f, named_list);
list_joined_nets (f, routed_list);
fprintf (f
, "-- Alias list here --\n");
list_routed_aliased_nets (f, named_list);
list_routed_aliased_nets (f, routed_list);
list_aliased_nets (f, unrouted_list);
}
/* ********************************************************************** */
/* if options & PRINT_ALL then print all known pins on the device */
/* if options & PRINT_TYPE then print the VHDL data type of this pin */
/* if options & PRINT_GENERIC then print out the device's generic map here also */
/* if options & PRINT_EXPAND_BUS then expand out the VHDL bus to individual wires */
/* if options & PRINT_GROUP then print out the pin groups */
/* if options & PRINT_ROUTE_FLAGS then print out the routing flags */
/* if options & PRINT_AS_UNROUTED then printout "UNROUTED" instead of any pindir info */
/* if options & PRINT_EQUIVALENT_PINS then print the list of pin equivalents */
void print_device (FILE *f, socket_t *dev, int options)
{
node_t *n;
char *vhdl_bus_format;
generic_info_t gen[1];
/* sort all the nodes into alphabetical order */
sort_nodes (dev, NO_EXTRACT_XY);
/* if we are using VHDL then look at the VHDL bus formatting tail*/
if ((options & PRINT_EXPAND_BUS) &&
get_generic_value (&global_generics, "vhdl_bus_format", gen) == IS_ENV_VAL &&
gen->expr)
vhdl_bus_format = gen->expr->left.s;
else
vhdl_bus_format = "_%d_"; /* persuade GCC the string pointer is modifiable */
/* if it hasnt got a name, use its identifier */
if (!dev->is_template)
{
if (dev->name != NULL && dev->name[0])
fprintf (f
, "CHIP %s\n", check_null_str
(dev
->name
));
else
fprintf (f
, "CHIP %s\n", dev
->identifier
);
fprintf (f
, "BEGIN\n DEVICE = \"%s\";\n", check_null_str
(dev
->type
));
if (options & PRINT_ROUTE_FLAGS && dev->route_flags)
fprintf (f
, " ROUTE_FLAGS = %d;\n", dev
->route_flags
);
if (dev->is_external)
fprintf (f
, "-- External Connection\n\n");
else
fprintf (f
, "-- Internal Socket\n\n");
fprintf (f
, "-- DEV_IDENT \"%s\"\n", dev
->identifier
);
if (dev->highest_bundle)
{
fprintf (f
, "-- Bundle of %d pins\n", dev
->highest_bundle
);
fprintf (f
, "-- min_pin_row %d\n", dev
->min_pin_row
);
fprintf (f
, "-- max_pin_row %d\n", dev
->max_pin_row
);
fprintf (f
, "-- min_pin_col %d\n", dev
->min_pin_col
);
fprintf (f
, "-- max_pin_col %d\n", dev
->max_pin_col
);
}
}
else
{
fprintf (f
, "TEMPLATE \"%s\"\n", check_null_str
(dev
->type
));
};
if (options & PRINT_GENERIC && dev->generics)
list_generic_values (f, &dev->generics, 2);
if (dev->is_template && dev->parent_template_ref)
{
f, " ALIAS \"%s\"\n", check_null_str (dev->parent_template_ref->type));
n = NULL; /* alias templates have no nodes of their own */
}
else
n = dev->nodes;
if (options & NO_PRINT_PINS)
n = NULL;
while (n)
{
char tmp_name[MAXIDLEN], vhdltail[MAXIDLEN], group_tail[MAXIDLEN];
int iter, iter_hi, iter_low;
vhdl_t *vhdl;
if (n->net_assigned || (options & PRINT_ALL) || dev->is_template ||
((options & PRINT_NET_NAMES) && n->routed_net &&
!ISNULLSTR (n->routed_net->name)))
{
/* there is a possibility here of printing
out a bus as separate signals */
if (n->orig_vhdltype) /* if a pin rename has taken place, use the
original name !! */
vhdl = n->orig_vhdltype;
else
vhdl = n->vhdltype;
if ((options & PRINT_EXPAND_BUS) && vhdl && vhdl->is_vector)
{
fprintf (f
, "-- Bus expansion follows '");
decode_vhdl_bus (f, vhdl, NO_RECURSE);
eval_vhdl_expression (vhdl->expr, &iter_hi, &iter_low);
if (iter_hi < iter_low)
{
int t;
fprintf (f
, "-- VHDL Range is backwards !! \n");
t = iter_hi;
iter_hi = iter_low;
iter_low = t;
};
}
else
{
iter_hi = 0;
iter_low = 0;
}
for (iter = iter_low; iter <= iter_hi; iter++)
{
/* create a tail on the signal name */
vhdltail[0] = '\0';
if (vhdl && vhdl->is_vector)
vhdltail,
vhdl_bus_format,
iter); /* this should be a template : setup in
symbol table */
if (options & PRINT_USABLE)
{
if (n->routed_net)
tmp_name,
"\"%s%s\"",
check_null_str (n->net->identifier),
vhdltail);
else
sprintf (tmp_name
, "\"unknown_net\"");
}
else if (options & PRINT_NET_NAMES) /* signal assigned to net
regardless of whether
routed to this pin */
{
if (n->net)
tmp_name,
"\"%s%s\"",
check_null_str (n->net->name),
vhdltail);
else if (n->routed_net)
tmp_name,
"\"%s%s\"",
check_null_str (n->routed_net->name),
vhdltail);
}
else
{
tmp_name,
"\"%s%s\"",
check_null_str (n->name),
vhdltail);
}
group_tail[0] = '\0';
if ((options & PRINT_GROUP) && n->pin_group)
sprintf (group_tail
, "(%d)", n
->pin_group
);
fprintf (f
, " %-32s : ", tmp_name
);
if (options & PRINT_AS_UNROUTED)
else
f,
"%s%s = %4s%s ",
decode_pin[(int) n->pindir],
group_tail,
n->identifier,
vhdltail);
if (options & PRINT_TYPE)
{
if (!vhdl) /* VHDL base types only are printed here as
vectors are expanded */
f,
" : %s",
default_vhdl_datatype->basetype);
else
fprintf (f
, " : %s", vhdl
->basetype
);
}
f,
"; -- refs=%d %s %s %s\n",
n->refcount,
n->fixed_pin ? "fixed" : "",
n->in_use ? "in use" : "unused",
n->net_assigned ? "net assigned" : "");
};
}
n = n->sktnext; /* traverse to next pin on socket */
};
/* use routine in equivalent.c */
if (options & PRINT_EQUIVALENT_PINS)
list_equivalent_pins (f, dev);
}
/************************************************************************/
/* this function prints the 'entity' of a top level of a partition as an
ACFP file */
void print_ACF_entity (FILE *f, char *entityname)
{
net_t *net = named_list;
int pin_num = 1;
fprintf (f
, "CHIP %s\n", entityname
);
fprintf (f
, "BEGIN\n DEVICE = \"VHDL-TOP\";\n");
while (net)
{
if (net->leaves_partition)
{
char nam[MAXIDLEN];
sprintf (nam
, "\"%s\"", check_null_str
(net
->name
));
f,
" %-32s : %5s = \"%d\" ",
nam,
decode_pin[(int) net->ext_dir],
pin_num++);
decode_vhdl_type (f, net->vhdltype, 0);
}
net = net->next;
}
fprintf (f
, "END; -- %s\n\n", entityname
);
}
/************************************************************************/
/* devices are always listed in acfp files with VHDL data types */
void list_devices (FILE *f, int listflags)
{
socket_t *dev;
dev = socket_head;
while (dev)
{
/* only print named devices !!! */
if (!ISNULLSTR (dev->name))
print_device (f, dev, listflags);
dev = dev->next;
};
}
/************************************************************************/
/* devices are always listed in acfp files with VHDL data types */
/* only those with their is_external flags set */
void list_extern_devices (FILE *f)
{
socket_t *dev;
dev = socket_head;
while (dev)
{
/* only print external devices !!! */
if (dev->is_external)
print_device (f, dev, PRINT_TYPE | PRINT_NET_NAMES);
dev = dev->next;
};
}
/************************************************************************/
static int list_pin_renames (net_t *list, FILE *f, int any_renames_seen)
{
noderef_t *nodes, *ref;
if (!list)
return any_renames_seen;
while (list)
{
nodes = list->nodes;
while (nodes)
{
ref = nodes->base_noderef;
if (ref->orig_name)
{
if (!any_renames_seen)
{ /* overall, start the list if there is a rename */
fprintf (f
, "RENAME_PINS\n BEGIN\n");
any_renames_seen = 1;
}
if (ref->orig_vhdltype)
{
fprintf (f
, " %s", list
->identifier
);
decode_vhdl_bus (f, ref->vhdltype, 0);
}
else
fprintf (f
, " %s = ( ", list
->identifier
);
f,
"%s.%s;);\n",
ref->node->socket->identifier,
ref->orig_name);
}
nodes = nodes->next;
}
list = list->next;
}
return (any_renames_seen);
}
/************************************************************************/
void print_pin_renames (FILE *f)
{
int any_renames_seen = 0;
fprintf (f
, "-- pin renames on unrouted list follow --\n");
list_pin_renames (unrouted_list, f, any_renames_seen);
fprintf (f
, "-- pin renames on routed list follow --\n");
any_renames_seen = list_pin_renames (routed_list, f, any_renames_seen);
fprintf (f
, "-- pin renames on named list follow --\n");
any_renames_seen = list_pin_renames (named_list, f, any_renames_seen);
if (any_renames_seen)
}
/************************************************************************/
/************************************************************************/
/* and now for the FRB formatted stuff */
/* prints a frb formatted net */
void frb_list_net (FILE *f, net_t *cnet)
{
noderef_t *bnode;
node_t *cnode;
bnode = cnet->nodes;
if (bnode)
{ /* only print out a net that has at leat one node on it */
cnode = bnode->node;
f,
".ADD_TER %s %s %s\n",
cnode->socket->identifier,
cnode->identifier,
cnet->identifier);
bnode = bnode->next;
if (bnode)
while (bnode)
{
cnode = bnode->node;
fprintf (f
, "%s %s\n", cnode
->socket
->identifier
, cnode
->identifier
);
bnode = bnode->next;
};
};
}
/* ********************************************************************** */
/* only jumpered nets are permitted to be listed as separate physical nets*/
/* aliased nets cannot, as they are asingle physical net */
void frb_list_net_connections (FILE *f, net_t *cnet)
{
while (cnet)
{
net_t *subnet = cnet->subnets;
if (subnet && cnet->how_joined == Jumpered)
{
while (subnet)
{
frb_list_net (f, subnet);
subnet = subnet->subnets;
}
}
else
frb_list_net (f, cnet);
cnet = cnet->next;
};
}
/* ********************************************************************** */
void produce_frb (FILE *f)
{
time_t now;
struct tm *tim;
socket_t *dev;
f,
".HEA\n.TIM %4d %02d %02d %02d %02d %02d\n",
tim->tm_year + 1900,
tim->tm_mon + 1, /* tm_mon has range 0..11 (jan=0) */
tim->tm_mday, /* but tm_mday has range 1..31 !! */
tim->tm_hour,
tim->tm_min,
tim->tm_sec);
fprintf (f
, ".JOB J_%d\n", (int) now
);
fprintf (f
, ".APP \"Neutral Architecture File\"\n\n");
dev = socket_head;
while (dev)
{
/* only print named devices !!! */
fprintf (f
, ".ADD_COM %s %s %s\n", dev
->identifier
, dev
->type
, dev
->value
);
dev = dev->next;
}
frb_list_net_connections (f, named_list);
frb_list_net_connections (f, routed_list);
}
/* ********************************************************************** */
#if defined PC
#define FMT1STR " Produced by %s (PC-CygWin)\n"
#define FMT2STR " at %02d:%02d:%02d on %02d/%02d/%4d \n\n"
#else
#define FMT1STR " Produced by %s (HPUX)\n"
#define FMT2STR " at %02d:%02d:%02d on %02d/%02d/%4d \n\n"
#endif
#define VHDL_FMTSTR "--" FMT1STR "--" FMT2STR
#define VLOG_FMTSTR "/*" FMT1STR " *" FMT2STR "*/"
/* puts a comment on the head of the file */
void print_header (FILE *f, char *tool)
{
time_t now;
struct tm *tim;
fprintf (f
, "-- FPGA / EPLD / PCB / VHDL tools --\n");
fprintf (f
, "-- NFL Technologies 1995-2003 --\n\n");
fprintf (f
, "-- by: Mike James \n\n");
f, "-- package version: %s compiled: %s--\n\n", Vertical_Version, Vertical_Time);
f,
VHDL_FMTSTR,
tool,
tim->tm_hour,
tim->tm_min,
tim->tm_sec,
tim->tm_mday,
tim->tm_mon + 1,
tim->tm_year + 1900);
}
/* puts a comment on the head of the file */
void print_VLOG_header (FILE *f, char *tool)
{
time_t now;
struct tm *tim;
fprintf (f
, "/* FPGA / EPLD / PCB / VHDL tools */\n");
fprintf (f
, "/* NFL Technologies 1995-2003 --\n\n */");
fprintf (f
, "/* by: Mike James \n\n */");
f, "/* package version: %s compiled: %s*/\n\n", Vertical_Version, Vertical_Time);
f,
VLOG_FMTSTR,
tool,
tim->tm_hour,
tim->tm_min,
tim->tm_sec,
tim->tm_mday,
tim->tm_mon + 1,
tim->tm_year + 1900);
}