/*
* $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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <regex.h>
#include "vertcl_main.h"
#include "expression.h"
#include "generic.h"
#include "database.h"
#include "cmdparse.h"
#include "cmdlog.h"
#include "printout.h"
#include "print_vlog.h"
#include "chck_names.h"
#include "template.h"
#include "sorting.h"
#include "unrouted.h"
#include "routing.h"
#include "equivalent.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,"-- changing pin ID '%s' to new ID = %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");
}