/*
* $Id: diagnostics.c,v 1.1.1.1 2003/11/04 23:34:56 mjames Exp $
*
* $Log: diagnostics.c,v $
* Revision 1.1.1.1 2003/11/04 23:34:56 mjames
* Imported into local repositrory
*
* Revision 1.4 2002/09/09 10:26:56 mjames
* Removed set generic range and replaced it with a set generic value command
* that takes both integers and ranges.
*
* Revision 1.3 2001/10/31 22:20:02 mjames
* Tidying up problematical comments caused by CVS
* 'intelligent' comment guessing
*
* Revision 1.2 2001/06/06 12:10:23 mjames
* Move from HPUX
*
* Revision 1.1.1.1 2000/10/19 21:58:36 mjames
* Mike put it here
*
*
* Revision 1.20 2000/10/04 10:37:03 10:37:03 mjames (Mike James)
* Modified for Vertical2 : support COMPONENTS and SIGNALS
*
* Revision 1.20 2000/10/04 10:37:03 10:37:03 mjames (Mike James)
* Part of Release PSAVAT01
*
* Revision 1.19 2000/10/02 11:04:11 11:04:11 mjames (Mike James)
* new_vhdl
*
* Revision 1.18 2000/09/27 14:42:11 14:42:11 mjames (Mike James)
* Part of Release Sep_27_ST_2000
*
* Revision 1.17 2000/09/21 10:15:41 10:15:41 mjames (Mike James)
* Part of Release Sep21Alpha
*
* Revision 1.16 2000/08/25 09:57:10 09:57:10 mjames (Mike James)
* Part of Release Aug25_alpha
*
* Revision 1.15 2000/08/16 08:57:26 08:57:26 mjames (Mike James)
* Part of Release CD01_Aug2000
*
* Revision 1.14 2000/08/14 14:45:08 14:45:08 mjames (Mike James)
* Part of Release Aug_14_2000
*
* Revision 1.13 2000/08/11 08:30:28 08:30:28 mjames (Mike James)
* Part of Release Aug_11_2000
*
* Revision 1.12 2000/08/09 10:31:42 10:31:42 mjames (Mike James)
* Part of Release Aug__9_2000
*
* Revision 1.11 2000/05/31 11:42:50 11:42:50 mjames (Mike James)
* Part of Release May_31_2000
*
* Revision 1.10 2000/05/08 17:01:33 17:01:33 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.9 2000/05/08 16:59:26 16:59:26 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.8 2000/05/08 16:57:03 16:57:03 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.7 2000/03/08 16:18:54 16:18:54 mjames (Mike James)
* New version including PC
*
* Revision 1.4 2000/01/20 15:58:42 15:58:42 mjames (Mike James)
* Part of Release R22
*
* Revision 1.3 99/12/22 11:15:22 11:15:22 mjames (Mike James)
* Part of Release Dec_22_1999
*
* Revision 1.2 99/06/25 14:34:43 14:34:43 mjames (Mike James)
* Added in reference to expression.h, but no changes made
* to the function of acfread yet.
*
* Revision 1.1 99/05/04 09:50:53 09:50:53 mjames (Mike James)
* Initial revision
*
*
*/
#include "cmdlog.h"
#include "cmdparse.h"
#include "database.h"
#include "generic.h"
#include "printout.h"
#include "sorting.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
static char IDstr[] = "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/spares/diagnostics.c,v 1.1.1.1 "
"2003/11/04 23:34:56 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"};
/* Decoding pin direction in VHDL */
static char *decode_pin_VHDL[] =
{
"-NONE-",
"IN",
"OUT",
"BUFFER", /* buffer is a sort of Output pin */
"INOUT",
"CONFIG_PIN"};
/* ********************************************************************** */
/* 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);
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)
{
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);
while (subnet)
{
list_net_structure (f, subnet, root_net, 0); /* depth = 0, not aliased
*/
subnet = subnet->joined_nets;
}
}
else if (cnet->how_joined == Aliased && subnet)
{
list_net_nodes (f, subnet, 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, 0 /*alias_depth+1*/);
subnet = subnet->joined_nets;
}
}
else if (!subnet)
list_net_nodes (f, cnet, root_net);
else
fprintf (f
, "-- Id %s skip\n", cnet
->identifier
);
}
/* ********************************************************************** */
/* lists all the connections on the board */
void list_nets (FILE *f, net_t *cnet)
{
while (cnet)
{
list_net_structure (f, cnet, cnet, 0);
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)
{
nettype = join == Aliased ? "ALIAS" : "JUMPER";
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);
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)
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;
};
}
/************************************************************************/
void list_database (FILE *f)
{
list_components (f);
fprintf (f
, "WIRED_NETS\nBEGIN\n");
fprintf (f
, "-- Routed & Named nets follow --\n");
list_nets (f, named_list);
fprintf (f
, "-- Routed & unused nets follow --\n");
list_nets (f, routed_list);
fprintf (f
, "-- Unrouted nets follow --\n");
list_nets (f, unrouted_list);
}
/************************************************************************/
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 */
void print_device (FILE *f, socket_t *dev, int options)
{
node_t *n;
char *vhdl_bus_format = "_%d_";
generic_info_t gen[1];
/* sort all the nodes into alphabetical order */
sort_nodes (dev);
/* 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_STRING)
vhdl_bus_format = gen->valuename;
/* 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
));
fprintf (f
, "-- DEV_IDENT \"%s\"\n", dev
->identifier
);
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");
if (options & PRINT_GENERIC && dev->generics)
list_generic_values (f, &dev->generics, 2);
}
else
{
fprintf (f
, "TEMPLATE \"%s\"\n", check_null_str
(dev
->name
));
};
if (dev->is_template && dev->parent_template_ref)
{
fprintf (f
, " ALIAS \"%s\"\n", check_null_str
(dev
->name
));
n = NULL; /* alias templates have no nodes of their own */
}
else
n = dev->nodes;
while (n)
{
char tmp_name[MAXIDLEN], typ[MAXIDLEN], vhdltail[MAXIDLEN],
group_tail[MAXIDLEN];
int iter, iter_hi, iter_low;
vhdl_t *vhdl;
if (n->net_assigned || (options & PRINT_ALL))
{
/* 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)
{
f,
"-- Bus expansion follows '%s'\n",
decode_vhdl_bus (vhdltail, vhdl));
iter_hi = vhdl->high;
iter_low = vhdl->low;
if (iter_hi < iter_low)
{
fprintf (f
, "-- VHDL Range is backwards !! \n");
iter_hi = vhdl->low;
iter_low = vhdl->high;
};
}
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
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
);
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 %n\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 */
};
}
/************************************************************************/
/* 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], typ[MAXIDLEN];
sprintf (nam
, "\"%s\"", check_null_str
(net
->name
));
f,
" %-32s : %5s = \"%d\" ",
nam,
decode_pin[(int) net->ext_dir],
pin_num++);
f,
" : \"%s\";\n",
decode_vhdl_type (typ, net->vhdltype));
}
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)
{
socket_t *dev;
dev = socket_head;
while (dev)
{
/* only print named devices !!! */
if (dev->name[0] != 0 && dev->name != nullstr)
print_device (
f,
dev,
PRINT_TYPE | PRINT_EXPAND_BUS |
PRINT_GENERIC | PRINT_GROUP |
PRINT_ROUTE_FLAGS);
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);
dev = dev->next;
};
}
/************************************************************************/
static int list_pin_renames (net_t *list, FILE *f, int any_renames_seen)
{
noderef_t *nodes, *ref;
int ref_renames_seen;
char vhdltext[MAXIDLEN];
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)
f,
" %s%s = ( ",
list->identifier,
decode_vhdl_bus (vhdltext, ref->vhdltype));
else
fprintf (f
, " %s = ( ", list
->identifier
);
f, "%s.%s;);\n", ref->node->socket->name, 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
, ".APP \"Neutral Architecture File\"\n\n");
dev = socket_head;
while (dev)
{
/* only print named devices !!! */
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);
}
/* ********************************************************************** */
/* puts a comment on the head of the file */
void print_header (FILE *f, char *tool)
{
time_t now;
struct tm *tim;
fprintf (f
, "-- Altera EPLD / PCB / VHDL tools --\n");
fprintf (f
, "-- (c) Philips Semiconductors Southampton 1996-1999 --\n\n");
fprintf (f
, "-- by: Mike James (Mike.James@soton.sc.philips.com)\n\n");
f,
"-- Produced by %s\n-- at %02d:%02d:%02d on %02d/%02d/%4d \n\n",
tool,
tim->tm_hour,
tim->tm_min,
tim->tm_sec,
tim->tm_mday,
tim->tm_mon + 1,
tim->tm_year + 1900);
}
/* ********************************************************************** */
/* VHDL output of the entities */
/* ********************************************************************** */
char *make_vhdl_name (char *buffer, char *str)
{
int i, l;
strcpy (buffer
, str
); /* should be a call to strncpy !! */
/* edit out illegal strings from the net name */
for (i = 0; i < l; i++)
{
if (buffer[i] == ':' || buffer[i] == '|')
buffer[i] = 'X';
}
i = l - 1;
/* convert pin indices back from Altera form if we are looking at FIT files */
if (l)
{
/* name ends in underscore, this forces mapping name_nn_ --> name(nn) */
if (buffer[i] == '_')
{
buffer[i--] = ')';
while (i >= 0 && buffer[i] != '_')
i--;
if (i >= 0)
buffer[i] = '(';
}
}
return buffer;
}
/* ********************************************************************** */
/* print out a VHDL component declaration */
void print_VHDL_component (FILE *f, socket_t *dev, int All)
{
node_t *n;
/* sort the identifiers of the nodes */
sort_nodes (dev);
fprintf (f
, "COMPONENT %s\n", check_null_str
(dev
->name
));
fprintf (f
, "-- DEV_IDENT \"%s\"\n\n", check_null_str
(dev
->identifier
));
/* sort the identifiers of the nodes */
sort_nodes (dev);
n = dev->nodes;
while (n)
{
vhdl_t *pin_datatype = default_vhdl_datatype;
char nam[MAXIDLEN], typ[MAXIDLEN];
if (n->orig_vhdltype)
pin_datatype = n->orig_vhdltype;
else if (n->vhdltype)
pin_datatype = n->vhdltype;
if (n->net_assigned && n->in_use || All)
{
f,
" %-16s : %6s %10s ",
make_vhdl_name (nam, check_null_str (n->name)),
decode_pin_VHDL[(int) n->pindir],
decode_vhdl_type (typ, pin_datatype));
if (n->sktnext)
f,
" -- i=%s r=%d --\n",
n->identifier,
n->refcount);
}
n = n->sktnext; /* traverse to next pin on socket */
};
fprintf (f
, ");\nEND COMPONENT;\n\n");
}
/* ********************************************************************** */
/* Printout an instance of a component */
/* ********************************************************************** */
void print_VHDL_instance (FILE *f, socket_t *dev, int All)
{
node_t *n;
int need_term = 0;
f,
"%s_inst : %s \n",
check_null_str (dev->name),
check_null_str (dev->name));
fprintf (f
, "-- DEV_IDENT \"%s\"\n\n", check_null_str
(dev
->identifier
));
/* sort the identifiers of the nodes */
sort_nodes (dev);
n = dev->nodes;
while (n)
{
vhdl_t *pin_datatype = default_vhdl_datatype;
char nam1[MAXIDLEN], nam2[MAXIDLEN], vhdlname[MAXIDLEN];
if (n->vhdltype)
pin_datatype = n->vhdltype;
if (n->net_assigned && n->in_use || All)
{
char *sig_prefix;
if (need_term)
else
need_term = 1;
/* is there a slice in the output */
if (n->net->needs_buff_sig)
sig_prefix = BUFPREFIX;
else
sig_prefix = "";
f,
" %-20s => %s%s %s ",
make_vhdl_name (nam1, check_null_str (n->name)),
sig_prefix,
make_vhdl_name (nam2, check_null_str (n->net->name)),
decode_vhdl_bus (vhdlname, n->vhdltype));
}
n = n->sktnext; /* traverse to next pin on socket */
};
}
/* ********************************************************************** */
void print_VHDL_sigs (FILE *f)
{
net_t *net = named_list;
char nam[MAXIDLEN], typ[MAXIDLEN], *sig_prefix;
while (net)
{
if (net->needs_buff_sig)
sig_prefix = BUFPREFIX;
else
sig_prefix = "";
if (net->inside_partition)
{
f,
" SIGNAL %s%s : %s;",
sig_prefix,
make_vhdl_name (nam, net->name),
decode_vhdl_type (typ, net->vhdltype));
}
else
f,
" -- net '%s%s : %sl",
sig_prefix,
make_vhdl_name (nam, net->name),
decode_vhdl_type (typ, net->vhdltype));
f,
" -- partition : %s, %s, %s --\n",
net->inside_partition ? "used in" : "unused in",
net->leaves_partition ? "leaves" : "buried ",
net->needs_buff_sig ? ", buffered" : "");
net = net->next;
}
}
/* ********************************************************************** */
void print_VHDL_assignments (FILE *f)
{
net_t *net = named_list;
fprintf (f
, "-- Buffered signals\n\n");
while (net)
{
if (net->inside_partition && net->needs_buff_sig)
{
char nam[MAXIDLEN];
make_vhdl_name (nam, net->name),
f,
" %s <= " BUFPREFIX "%s;\n",
nam,
nam);
}
net = net->next;
}
}
/* ********************************************************************** */
void print_VHDL_entity (FILE *f, char *entityname)
{
net_t *net = named_list;
int need_term = 0;
fprintf (f
, "ENTITY %s IS\n PORT (\n", entityname
);
while (net)
{
char nam[MAXIDLEN], typ[MAXIDLEN];
if (net->leaves_partition)
{
if (need_term)
else
f,
" %-15s : %6s %10s",
make_vhdl_name (nam, net->name),
decode_pin_VHDL[net->ext_dir],
decode_vhdl_type (typ, net->vhdltype));
need_term = 1;
}
net = net->next;
}
fprintf (f
, "END %s;\n\n", entityname
);
}
/* ********************************************************************** */
/* generate default VHDL Libraries */
/* ********************************************************************** */
void print_VHDL_libs (FILE *f)
{
fprintf (f
, "LIBRARY IEEE,WORK;\nUSE IEEE.std_logic_1164.ALL;\n\n");
}
/* ********************************************************************** */
/* generate a VHDL architecture forselected sockets */
/* ********************************************************************** */
void print_VHDL_architecture (FILE *f, char *entityname)
{
socket_t *skt;
fprintf (f
, "\n\nARCHITECTURE top OF %s IS\n\n", entityname
);
skt = socket_head;
while (skt)
{
if (skt->selected)
print_VHDL_component (f, skt, 0);
skt = skt->next;
}
print_VHDL_sigs (f);
skt = socket_head;
while (skt)
{
if (skt->selected)
print_VHDL_instance (f, skt, 0);
skt = skt->next;
}
print_VHDL_assignments (f);
}
/* ********************************************************************** */
/* generate a VHDL file */
/* ********************************************************************** */
void produce_VHDL (FILE *f, char *entityname, char *template)
{
char linebuff[256];
int done_entity = 0, done_architecture = 0;
if (!template || !template[0])
{ /* check null pointer or empty string */
print_header (f, "WRITE VHDL");
print_VHDL_libs (f);
print_VHDL_entity (f, entityname);
print_VHDL_libs (f);
print_VHDL_architecture (f, entityname);
}
else
{ /* there is a template file */
FILE *tp;
tp
= fopen (template
, "r");
if (tp)
{
print_header (f, "WRITE VHDL");
fprintf (f
, "-- Using template '%s'\n", template
);
{
if (fgets (linebuff
, 256, tp
))
{
if (strstr (linebuff
, "$ENT"))
{
print_VHDL_entity (f, entityname);
done_entity++;
}
else if (strstr (linebuff
, "$ARCH"))
{
print_VHDL_architecture (f, entityname);
done_architecture++;
}
else
fprintf (f
, "%s", linebuff
); /* it already has
a '\n' on the
end */
}
}
if (done_entity != 1)
Log (
LOG_ERROR,
"-- Error: %d $ENT$ tags counted in template '%s'\n",
template);
if (done_architecture != 1)
Log (
LOG_ERROR,
"-- Error: %d $ARCH$ tags counted in template '%s'\n",
template);
}
else
Log (
LOG_ERROR,
"-- Error: Cannot open VHDL template '%s'\n",
template);
}
}
/**********************************************************/
/* Database diagnostics */
/**********************************************************/
void deb_print_node (FILE *f, node_t *n)
{
/* struct node * sktnext; linked to a socket */
fprintf (f
, "next->%p\n", n
->sktnext
);
/* char * identifier; e.g 102, A22 */
fprintf (f
, "identifier %s\n", n
->identifier
);
/* char * name; signal name (actually same as netname ) */
fprintf (f
, "name %s\n", check_null_str
(n
->name
));
/* vhdl_t * vhdltype; */
fprintf (f
, "vhdltype %p\n", decode_vhdl_type
(n
->vhdltype
));
/* vhdl_t * orig_vhdltype; */
fprintf (f
, "orig_vhdltype %p\n", decode_vhdl_type
(n
->orig_vhdltype
));
/* pindir_t pindir; final pin type input? output? bidir? unknown? */
fprintf (f
, "pindir %s\n", decode_pin
[n
->pindir
]);
/* struct net * net; refer to net this node is on (if known) */
if (n->net)
fprintf (f
, " (id '%s')\n", check_null_str
(n
->net
->identifier
));
/* struct net * net; refer to net this node is on (if known) */
fprintf (f
, "routed net %p\n", n
->net
);
if (n->net)
fprintf (f
, " (id '%s')\n", check_null_str
(n
->net
->identifier
));
/* int refcount; how many nets refer to this node */
fprintf (f
, "refcount %d\n", n
->refcount
);
/* struct socket * socket; refer to socket this node is part of */
fprintf (f
, "socket %p\n", n
->socket
);
if (n->socket)
fprintf (f
, " socket (id '%s')\n", check_null_str
(n
->socket
->identifier
));
/* unsigned int fixed_pin:1; if fixed_pin = 1 then this pin can only be used
to connect to the net in a particular
direction */
fprintf (f
, "fixed_pin: %s\n", n
->fixed_pin
? "yes" : "no");
/* unsigned int in_use:1; if '1' the node is used by a pin
if '0' the node has had a dummy name assigned*/
fprintf (f
, "in_use: %s\n", n
->in_use
? "yes" : "no");
/* unsigned int net_assigned:1; if '1' the node (name) has a net assigned
to it by routing */
fprintf (f
, "net_assigned: %s\n", n
->net_assigned
? "yes" : "no");
}