/*
* $Id: template.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $ * This file ensures that for all
* sockets that are in
*
* $Log: template.c,v $
* Revision 1.1.1.1 2003/11/04 23:34:57 mjames
* Imported into local repositrory
*
* Revision 1.22 2003/01/02 21:37:18 mjames
* Experiment on creating NOT_ROUTABLE_H and NOT_ROUTABLE_L
* properties on the nets so that pin jumpers can be made without a problem.
*
* Still need to sort out pin assignments made to these not_routable nets
* which will become legal in some cases so that pullups and pulldown
* pins can be used on the FPGA.
*
* Revision 1.21 2002/12/09 10:31:50 mjames
* Corrected 2 warnings about #ident
* Added warning about "chip X1" which gets confused with component called "X1"
*
* Revision 1.20 2002/09/18 08:50:48 mjames
* Cleared 'use before assign' warning
*
* Revision 1.19 2002/09/09 10:14:26 mjames
* Moved pin remapping function to pin ident editing function from
* sorting pin name routine.
*
* Revision 1.18 2002/09/09 09:51:27 mjames
* Change to #ident
*
* Revision 1.17 2001/12/20 13:38:57 mjames
* Forced net not routable if fpga pin is disconnected from it. Brutal
*
* Revision 1.16 2001/12/11 21:26:18 mjames
* Corrected pin deletion by setting correct flags.
*
* Revision 1.15 2001/11/30 22:24:35 mjames
* Improved diagnostic debug messages.
* Used the correct sense of missing template
* pins to remove unused pins of the component.
*
* Revision 1.14 2001/11/19 10:41:34 mjames
* Merged back DTC release
*
* Revision 1.13.2.1 2001/11/15 22:01:53 mjames
* Added counters for diagnostics
*
* Revision 1.13 2001/11/01 11:01:33 mjames
* Template pins are created whether or not a net is routable.
*
* Revision 1.12 2001/10/31 22:20:18 mjames
* Tidying up problematical comments caused by CVS
* 'intelligent' comment guessing
*
* Revision 1.11 2001/10/31 16:18:04 mjames
* Added a datastructure to hide regular expression information from programs.
* Changed call to regexec to indicate 0 subexpressions to be matched
* rather than a number dependent on strlen(string) which was wrong.
*
* Revision 1.10 2001/10/22 10:45:45 mjames
* Added template options to create and /or disconnect pins on
* sockets according to flags passed in to the template core routine
*
* Revision 1.9 2001/10/10 20:18:20 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.8 2001/10/10 12:49:47 mjames
* Passed wrong argument to wildcard validator within template ensure . Fixed
*
* Revision 1.7 2001/10/07 20:50:51 mjames
* Added wildcard checking (warn user about
* using wildcard '*' on the end of a string in stead of wildcard '.*')
*
* Revision 1.6 2001/09/25 23:15:22 mjames
* Converted wildcards to use proper regexp pattern match library
*
* Revision 1.5 2001/09/21 14:23:28 mjames
* Cleared out template flags before checking pin compatibility rather than
* while checking.
*
* Revision 1.4 2001/07/16 15:54:57 MJAMES
* Conversion to correctly print port list of extracted components.
*
* Revision 1.3 2001/06/22 11:08:07 mjames
* Added a function to extract templates (common component types) from
* ACF style netlists. This then permits Verilog printout to avoid duplication
* of declaration ( problem before )
*
* Revision 1.2 2001/06/06 12:10:17 mjames
* Move from HPUX
*
* Revision 1.1.1.1 2000/10/19 21:58:40 mjames
* Mike put it here
*
*
* Revision 1.32 2000/10/12 14:27:52 14:27:52 mjames (Mike James)
* changed listing vhdl signals to expand expressions
* until a constant is located
*
* Revision 1.31 2000/10/04 10:37:10 10:37:10 mjames (Mike James)
* Modified for Vertical2 : support COMPONENTS and SIGNALS
*
* Revision 1.31 2000/10/04 10:37:10 10:37:10 mjames (Mike James)
* Part of Release PSAVAT01
*
* Revision 1.30 2000/10/02 11:04:21 11:04:21 mjames (Mike James)
* new_vhdl
*
* Revision 1.29 2000/09/27 14:42:22 14:42:22 mjames (Mike James)
* Part of Release Sep_27_ST_2000
*
* Revision 1.28 2000/09/21 10:15:52 10:15:52 mjames (Mike James)
* Part of Release Sep21Alpha
*
* Revision 1.27 2000/09/21 09:47:46 09:47:46 mjames (Mike James)
* Added code to handle pin equivalents in templates
* calling a function to copy over the pin equivalnets
* from a template.
*
*
* Revision 1.26 2000/08/25 09:57:17 09:57:17 mjames (Mike James)
* Part of Release Aug25_alpha
*
* Revision 1.25 2000/08/16 08:57:33 08:57:33 mjames (Mike James)
* Part of Release CD01_Aug2000
*
* Revision 1.24 2000/08/14 14:45:14 14:45:14 mjames (Mike James)
* Part of Release Aug_14_2000
*
* Revision 1.23 2000/08/14 14:43:37 14:43:37 mjames (Mike James)
* Added power pins
*
* Revision 1.22 2000/08/11 08:30:34 08:30:34 mjames (Mike James)
* Part of Release Aug_11_2000
*
* Revision 1.21 2000/08/09 10:31:50 10:31:50 mjames (Mike James)
* Part of Release Aug__9_2000
*
* Revision 1.20 2000/05/31 11:43:01 11:43:01 mjames (Mike James)
* Part of Release May_31_2000
*
* Revision 1.19 2000/05/08 17:01:40 17:01:40 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.18 2000/05/08 16:59:33 16:59:33 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.17 2000/05/08 16:57:10 16:57:10 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.16 2000/03/08 16:19:34 16:19:34 mjames (Mike James)
* New version including PC
*
* Revision 1.13 2000/01/20 15:58:51 15:58:51 mjames (Mike James)
* Part of Release R22
*
* Revision 1.12 99/12/22 11:15:32 11:15:32 mjames (Mike James)
* Part of Release Dec_22_1999
*
* Revision 1.11 99/11/23 13:55:21 13:55:21 mjames (Mike James)
* Added Certify support
*
* Revision 1.10 99/06/25 14:35:53 14:35:53 mjames (Mike James)
* Added in reference to expression.h, but no changes made
* to the function of acfread yet.
*
* Revision 1.9 99/06/18 09:26:33 09:26:33 mjames (Mike James)
* Templating behaviour still incorrect. Under investigation.
*
* Revision 1.8 98/11/30 11:58:59 11:58:59 mjames (Mike James)
* Altered behaviour for pins of type 'none' , also related
* stuff in unrouted.c, to set a pin direction on chip
* nodes when node references are made in the unnnamed list of
* pins.
*
* Revision 1.7 98/11/13 15:22:23 15:22:23 mjames (Mike James)
* Fixed core dump on non-existent pin identifier
* in template application function.
* Previously locating pins was called with
* a Create rather than Find flag. So it always retuned some pointer
* to some object. Now I use Find and it can return NULL. I needed to
* check for that null pointer.
*
* Revision 1.6 98/10/01 15:28:08 15:28:08 mjames (Mike James)
* Altered behaviour to search for pins on line 204
*
* Revision 1.5 98/08/12 14:23:02 14:23:02 mjames (Mike James)
* extending the templating algorithms
*
* Revision 1.4 98/07/14 13:26:39 13:26:39 mjames (Mike James)
* Now hase three levels of checking templates
*
* Revision 1.3 98/06/15 14:20:49 14:20:49 mjames (Mike James)
* Made tempaltes chip specific.
*
* Revision 1.2 98/02/11 11:27:29 11:27:29 mjames (Mike James)
* Checked in for version 6.2a
*
* Revision 1.1 97/04/23 08:43:27 08:43:27 mjames (Mike James)
* Initial revision
* */
#include "template.h"
#include "chck_names.h"
#include "cmdlog.h"
#include "cmdparse.h"
#include "database.h"
#include "equivalent.h"
#include "expression.h"
#include "generic.h"
#include "print_vlog.h"
#include "printout.h"
#include "routing.h"
#include "sorting.h"
#include "unrouted.h"
#include "vertcl_main.h"
#include <ctype.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ident \
"@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/template.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $"
/* We have to check all sockets to see if there is a template for them.
If there is then we ensure that all of the template pins exist on the main
chip socket */
/* the following pin table indicates if a device pin is compatible with a template pin */
/* compat_pins[device][template] : relies on the declaration of pindir_t */
/* The array is looked up by chip pin in the y direction and
template pin in the x direction */
char *compat_pins[] = {"1111110", /* NONE : is it best to claim it is compatible with all pins
: routing later will sort out mistakes here !*/
"0100100", /* INPUT */
"0011100", /* OUTPUT */
"0011100", /* BUFFER */
"0000100", /* BIDIR */
"0000010", /* CONFIG */
"0000001"}; /* POWER */
static char *decode_pin_dir[] = {"UNKNOWN",
"INPUT",
"OUTPUT",
"BUFFER", /* buffer is a sort of Output pin */
"BIDIR",
"CONFIG",
"POWER"}; /* added Aug 2000 */
/* The function here checks pin identifiers
* a) to see if the pin IDs on the chip match those on the template.
* b) to reassign any invalid pin IDs on the chip to valid
* compatible ones on the template.
* c) If options & TEMPLATE_CREATE_MISSING_PINS
* to create any remaining pin IDs on the chip that
* still are available on the template
* d) to make sure all fixed pin directions are OK
* e) If options & TEMPLATE_DISCONNECT_PINS to disconnect any pins
on the chip that are not present on the template
Any net that loses an FPGA pin is set not routable.
*/
void template_ensure (char *chip_id_template, int options)
{
socket_t *skt = socket_head, *template = NULL;
int found = 0, rc;
int pins_used, pins_count;
int chip_count, processed_count;
node_t *chip_node, *template_node;
char *pattern;
/* compile regular expression */
vert_regex_t *preg;
chip_count = 0;
processed_count = 0;
create_unrouted_list ();
/* pick out a wildcard if any ID given, else wildcard anyway */
if (!chip_id_template)
{
pattern = ".*";
Log (LOG_GENERAL, "-- Beginning setting pin template on all chips\n");
}
else
{
pattern = chip_id_template;
Log (
LOG_GENERAL,
"-- Beginning setting pin template: prefix '%s' --\n",
chip_id_template);
}
rc = vert_regcomp (&preg, pattern);
if (rc != 0)
{
char errbuff[100];
regerror (rc, preg->preg, errbuff, 100);
Log (
LOG_ERROR,
"-- Problem (rc=%d) %s with '%s' as regular expression\n",
rc,
errbuff,
pattern);
/* return TCL_ERROR;
*/
return;
}
else
{
Log (LOG_GENERAL, "-- Using '%s' as match pattern\n", pattern);
}
while (skt)
{
chip_count++;
skt->template_socket = NULL;
found = regexec (preg->preg, skt->identifier, 0, preg->regpatt, 0);
if (!found)
{
char *chiptype = skt->type;
if (!ISNULLSTR (chiptype))
{
template =
find_socket (Type, chiptype, Search, &template_head);
if (level & 1)
{
Log (
LOG_GENERAL,
"-- **** Processing chip '%s' : type='%s' ****\n",
skt->identifier,
chiptype);
}
/* assign_declaration_directives(skt,global_generics);
*/
if (template)
{ /* we have located a template for this chip */
processed_count++;
skt->template_socket = template;
if (level & 1)
{
Log (LOG_GENERAL, "-- Which has a template\n");
}
/* examine all of the template entries and add in any
IS_DECLARATION_DIRECTIVE ones */
assign_declaration_directives (
skt, template->generics);
/*
copy_declaration_generics(skt,template);
*/
/* clear template flags on chip nodes */
chip_node = skt->nodes;
while (chip_node)
{
chip_node->template_flag = 0;
chip_node = chip_node->sktnext;
}
template_node = template->nodes;
while (template_node)
{
template_node->template_flag = 0;
template_node = template_node->sktnext;
}
/* search for nodes that already have valid identifiers
according to the chip templates, and mark these as
being OK */
template_node = template->nodes;
if (level & 1)
{
Log (
LOG_GENERAL,
"-- Matching template node identifiers\n");
}
while (template_node)
{
chip_node = find_node (
skt,
Ident,
template_node->identifier,
Search);
if (chip_node)
{
/* need also to confirm that this pin
connection is of a compatible type
-- added checking code here */
if (level & 2)
Log (
LOG_GENERAL,
"-- node '%s' chip=%d "
"template=%d compat %c\n",
chip_node->identifier,
chip_node->pindir,
template_node->pindir,
compat_pins[chip_node
->pindir]
[template_node
->pindir]);
if (compat_pins[chip_node->pindir]
[template_node
->pindir] == '1')
{
chip_node
->vhdltype = copy_vhdl (
template_node->vhdltype,
skt);
template_node->template_flag =
1;
chip_node->template_flag = 1;
if (level & 2)
Log (
LOG_GENERAL,
"-- pin '%s' "
"compatible\n",
template_node
->identifier);
}
};
/*
else
Log(LOG_GENERAL,"-- node '%s' not
matched\n",template_node->identifier);
*/
template_node = template_node->sktnext;
}
/* now look through chip for all identifiers that
havent been found on the template. These are
incorrect and need to be replaced by an unused
template pin*/
if (level & 1)
{
Log (
LOG_GENERAL,
"-- Altering node identifiers\n");
}
/* clear template flags on chip nodes */
chip_node = skt->nodes;
/* search each chip node to see if validated OK */
while (chip_node)
{
/* if it does not have a correct template pin ,
* go and find one */
if (!chip_node->template_flag)
{
template_node = template->nodes;
while (template_node)
{
if (template_node
->template_flag == 0)
{
/* possible pin unused
* candidate : look at
* the pin direction */
if (compat_pins
[chip_node
->pindir]
[template_node
->pindir] ==
'1')
{
template_node
->template_flag =
1;
chip_node
->template_flag =
1;
if (level & 2)
Log (
LOG_GENERAL,
"-"
"-"
" "
"c"
"h"
"a"
"n"
"g"
"i"
"n"
"g"
" "
"p"
"i"
"n"
" "
"I"
"D"
" "
"'"
"%"
"s"
"'"
" "
"t"
"o"
" "
"n"
"e"
"w"
" "
"I"
"D"
" "
"="
" "
"%"
"s"
"\n",
chip_node
->identifier,
template_node
->identifier);
chip_node
->identifier =
template_node
->identifier;
chip_node
->vhdltype =
copy_vhdl (
template_node
->vhdltype,
skt);
break; /* from
while
template_node
*/
}
/*
else
Log(LOG_GENERAL,"--
?? node ID '%s' new ID
= %s .. %d\n",
chip_node->identifier,
template_node->identifier,template_node->pindir);
*/
}
template_node =
template_node->sktnext;
}
/* if we havent found a valid possible
template node ID for the chip pin
then template_node == NULL at this
point (run out of possibilities)
Except if we are deleting missing
pins then its worth */
if (!(options &
TEMPLATE_DISCONNECT_PINS) &&
!template_node)
Log (
LOG_ERROR,
"-- ERROR (perhaps): "
"Cannot find a valid ID "
"to replace %s pin '%s'\n",
decode_pin_dir
[chip_node->pindir],
chip_node->identifier);
}
chip_node = chip_node->sktnext;
}
if (level & 1)
{
Log (
LOG_GENERAL,
"-- Creating additional pins , correcting "
"fixed pin directions\n");
}
/* to apply template :
Find/create the chip pin . If the
matching template pin directional is BIDIR_PIN,
do not touch the current pin direction.
Otherwise override the physical pin direction */
template_node = template->nodes;
pins_used = 0;
pins_count = 0;
while (template_node)
{
/* find the chip pin (node) */
node_t *chip_node;
chip_node = find_node (
skt,
Ident,
template_node->identifier,
options & TEMPLATE_CREATE_MISSING_PINS);
if (level & 2)
{
Log (
LOG_GENERAL,
"-- template '%s' template flag "
"%d exists %d\n",
template_node->identifier,
template_node->template_flag,
chip_node ? 1 : 0);
}
pins_count++;
if (chip_node != NULL)
{
pins_used++;
/* fix the pin direction down !! */
if (template_node->template_flag == 0)
{
/* next line had chip_node in
* it */
if ((template_node->pindir !=
BIDIR) &&
(template_node->pindir !=
NONE))
{
chip_node->fixed_pin =
1; /* routes must
use the
appropriate
pin direction
*/
chip_node->pindir =
template_node
->pindir;
if (level & 2)
Log (
LOG_GENERAL,
"-- pin "
"'%s' "
"fixing "
"pindir "
"as %d\n",
chip_node
->identifier,
chip_node
->pindir);
}
}
chip_node->template_flag =
1; /* templating applied OK */
chip_node->pin_group =
template_node->pin_group;
}
template_node = template_node->sktnext;
}
if (level & 1)
{
Log (
LOG_GENERAL,
"-- %d pins out of %d in use\n",
pins_used,
pins_count);
}
}
/* new stuff October 2001 : If any chip pins do not have their
template flag set now then
they _may_ be deleted as they are not on the template in any
case */
if (template && (options & TEMPLATE_DISCONNECT_PINS))
{
pins_count = 0;
if (level & 1)
{
Log (
LOG_GENERAL,
"-- Disconnecting pins missing on "
"template\n");
}
chip_node = skt->nodes;
while (chip_node)
{
if (!chip_node->template_flag)
{
if (level & 2)
{
Log (
LOG_GENERAL,
"-- pin '%s' being "
"disconnected\n",
chip_node->identifier);
}
pins_count++;
/* questionable approach to problem */
if (chip_node->net)
{
chip_node->net->how_routed =
Not_Routable; /* checked */
}
disconnect_node (skt, chip_node);
}
chip_node = chip_node->sktnext;
}
if (level & 1)
{
Log (
LOG_GENERAL,
"-- Disconnected %d pins missing on "
"template\n",
pins_count);
}
}
if (level & 1)
{
Log (LOG_GENERAL, "-- Finished chip\n");
}
}
copy_equivalent_pins (
template, skt); /* any pin connections that are equivalent
by default will be copied from the template */
}
skt = skt->next;
}
Log (
LOG_GENERAL,
"-- checked %d objects, applied template to %d of them\n",
chip_count,
processed_count);
vert_regfree (&preg);
}
/* list what we have as a template */
void template_list (void)
{
socket_t *templates = template_head;
/* for now list out the templates */
Log (LOG_GENERAL, "-- List of socket templates\n");
while (templates)
{
Log (LOG_GENERAL, "-- Template '%s' ", templates->type);
if (templates->parent_template_ref)
Log (
LOG_GENERAL, "alias '%s'\n", templates->parent_template_ref->type);
else
Log (LOG_GENERAL, "\n");
templates = templates->next;
}
}
/* list what we have as a template */
void template_list_pins (FILE *f)
{
socket_t *templates = template_head;
/* for now list out the templates */
while (templates)
{
fprintf (f
, "-- Template '%s'\n", templates
->type
);
print_device (
f,
templates,
PRINT_ALL | PRINT_GROUP | PRINT_GENERIC | PRINT_EQUIVALENT_PINS |
PRINT_EXPAND_BUS);
templates = templates->next;
}
}
/******************************************************************************************/
/* Extracting component templates from the list of components in the circuit design */
/******************************************************************************************/
void extract_templates (void)
{
socket_t *skt = socket_head, *template;
node_t *chip_node, *template_node;
Log (
LOG_GENERAL,
"-- Extracting device templates (verilog modules or VHDL components)\n");
/* is this needed ? */
create_unrouted_list ();
while (skt)
{
char *chiptype = skt->type;
/* locate or create the template for this socket */
if (!ISNULLSTR (chiptype))
{
template = find_socket (Type, chiptype, Search, &template_head);
skt->template_socket = template;
if (!template) /* act only if no template */
{
if (level & 4)
Log (
LOG_GENERAL,
"-- Creating template from chip '%s' : "
"type='%s'\n",
skt->identifier,
chiptype);
template =
find_socket (Type, chiptype, Create, &template_head);
template->is_template = 1; /* flag for later use */
}
assign_declaration_directives (template, skt->generics);
skt->template_socket = template;
copy_equivalent_pins (
skt, template); /* any pin connections that are equivalent
by default will be copied to the template */
/* assign_declaration_directives(skt,template->generics); */
/*
copy_declaration_generics(skt,template);
*/
chip_node = skt->nodes;
if (level & 4)
Log (LOG_GENERAL, "-- Copying/checking node identifiers\n");
while (chip_node)
{
if (level & 4)
Log (
LOG_GENERAL,
"-- Node %s\n",
chip_node->identifier);
template_node =
find_node (template, Ident, chip_node->identifier, Search);
/* add pins to template if there is a net connected to this pin
* and it is routable */
if (!template_node && chip_node->net /*&& chip_node->net->how_routed != Not_Routable */ )
{
template_node = find_node (
template, Ident, chip_node->identifier, Create);
template_node->pindir = chip_node->pindir;
template_node->vhdltype =
copy_vhdl (chip_node->vhdltype, skt);
if (level & 4)
Log (
LOG_GENERAL,
"-- node '%s' dircode=%d\n",
template_node->identifier,
template_node->pindir);
}
chip_node = chip_node->sktnext;
}
if (level & 4)
{
Log (LOG_GENERAL, "-- Finished chip\n");
}
}
skt = skt->next;
}
Log (LOG_GENERAL, "-- Finished extracting device templates\n");
}