/* $Id: equivalent.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $ */
/*
* $Log: equivalent.c,v $
* Revision 1.1.1.1 2003/11/04 23:34:57 mjames
* Imported into local repositrory
*
* Revision 1.9 2003/01/02 21:37:15 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.8 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.7 2002/01/15 12:36:22 mjames
* DLL declarations put in,
*
* #ident used
*
* Revision 1.6 2001/11/01 11:06:49 mjames
* Simplified code for connection of equivalent node sets to components
*
* Revision 1.5 2001/10/31 22:20:03 mjames
* Tidying up problematical comments caused by CVS
* 'intelligent' comment guessing
*
*/
/* This file handles equivalent pins , being passthroughs or
low value resistors which can be regarded as passthrough jumpers */
/* Extracted from ACFREAD syntax : pin equivalences within a chip or template
declaration
pin_equivalence : EQUIVALENT LBRK { curr_equiv_list = begin_equivalent_pins(); }
equivalent_pins
RBRK end_item { check_equivalent_pins(current_chip,curr_equiv_list); }
;
equivalent_pins : equivalent_pin SEMI equivalent_pins
| equivalent_pin
|
;
equivalent_pin : astring { add_equivalent_pin( current_chip,curr_equiv_list,$1); };
in2 : input_pin = a1;
in3 : input_pin = f1;
e.g. EQUIVALENT ( a1;f1);
*/
/* we approach the storage of nodes with caution , deferring the
adding of information until it is correct */
#include "equivalent.h"
#include "cmdlog.h"
#include "cmdparse.h"
#include "database.h"
#include "expression.h"
#include "generic.h"
#include "jumpering.h"
#include "printout.h"
#include "vertcl_main.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ident \
"@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/equivalent.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $"
/********************************************************************/
/* this function starts to create a list of equivalent pins */
/********************************************************************/
equivalent_node_set_t *begin_equivalent_pins (void)
{
equivalent_node_set_t *node_set;
node_set
= calloc (1, sizeof (equivalent_node_set_t
));
return node_set;
}
/********************************************************************/
/* add a pin to the list referred to by node_set */
/********************************************************************/
void add_equivalent_pin (socket_t *current_chip, equivalent_node_set_t *node_set, char *ident)
{
equivalent_node_t *ptr;
equivalent_node_t *equiv_node;
node_t *node;
if (!current_chip)
{
Log (LOG_ERROR, "-- Current chip not known for equivalent pin creation\n");
return;
}
node = find_node (current_chip, Ident, ident, Create);
/* no pin called 'ident ?? */
if ((level & 1) && !node)
{
Log (
LOG_ERROR,
"-- Error : Pin Equivalent : cannot find pin %s(%s)\n",
current_chip->name,
ident);
return;
}
/* pin already equivalent to another ? */
if ((level & 1) && node->equivalent_nodes)
{
Log (
LOG_ERROR,
"-- Error : Pin Equivalent : pin %s(%s) already member of set\n",
current_chip->name,
ident);
return;
}
/* pin is acceptable so note it */
equiv_node
= calloc (1, sizeof (equivalent_node_t
));
if (!node_set->nodes)
{
/* new node */
node_set->nodes = equiv_node;
}
else
{
ptr = node_set->nodes;
while (ptr->next)
ptr = ptr->next;
ptr->next = equiv_node;
}
equiv_node->node = node;
}
/********************************************************************/
/* this function will verify the current list of nodes that are equivalent, and if there is
more than one in the list then it will add them to the equivalent node list of the
chip (if only one pin is equivalent to itself then it is a waste of time .... ) */
/********************************************************************/
void check_equivalent_pins (socket_t *current_chip, equivalent_node_set_t *node_set)
{
equivalent_node_t *curr_node, *prev;
int equiv_count;
if (!node_set)
return;
/* count equivalent nodes */
curr_node = node_set->nodes;
equiv_count = 0;
while (curr_node)
{
equiv_count++;
curr_node = curr_node->next;
};
/* delete info if not sufficent equivalent nodes */
if (equiv_count < 2)
{
curr_node = node_set->nodes;
while (curr_node)
{
prev = curr_node;
curr_node = curr_node->next;
};
Log (LOG_ERROR, "-- Warning : insufficient equivalent pins in list\n");
return;
}
/* join the list to the socket as it is now validated */
curr_node = node_set->nodes;
while (curr_node)
{
/* flag each node as being a member of an equivalent set */
curr_node->node->equivalent_nodes = node_set;
curr_node = curr_node->next;
}
/* add an additional equivalent node set */
node_set->next = current_chip->equivalent_node_set;
current_chip->equivalent_node_set = node_set;
return;
}
/********************************************************************/
void list_equivalent_pins (FILE *f, socket_t *dev)
{
int itemcnt;
equivalent_node_t *curr_node;
equivalent_node_set_t *curr_set;
curr_set = dev->equivalent_node_set;
while (curr_set)
{
if (curr_set->nodes)
{
curr_node = curr_set->nodes;
itemcnt = 2;
while (curr_node)
{
if (curr_node->next)
{
fprintf (f
, "%s; ", curr_node
->node
->identifier
);
itemcnt++;
if (itemcnt > 6)
{
itemcnt = 0;
}
}
else
fprintf (f
, "%s);\n", curr_node
->node
->identifier
);
curr_node = curr_node->next;
}
}
curr_set = curr_set->next;
}
}
/********************************************************************
* copies the equivalent pins list from template to device instance *
* uses the functions above to ensure validation is consistently *
* performed
********************************************************************/
void copy_equivalent_pins (socket_t *template, socket_t *dev)
{
equivalent_node_t *curr_node;
equivalent_node_set_t *curr_set, *new_set;
/* trap use of template when none is actually given */
if (!template || !dev)
return;
if (level & 1)
{
Log (
LOG_GENERAL,
"copying equivalent pins from template %s to socket %s\n",
template->type,
dev->identifier);
}
curr_set = template->equivalent_node_set;
while (curr_set)
{
new_set = begin_equivalent_pins ();
/* create a set of equivalent pins to copy into */
curr_node = curr_set->nodes;
while (curr_node)
{
add_equivalent_pin (dev, new_set, curr_node->node->identifier);
/* traverse list */
curr_node = curr_node->next;
}
check_equivalent_pins (dev, new_set);
curr_set = curr_set->next;
}
}
/* function to jumper together all equivalent pins on a device :
at the moment it does not distinguish between EPLD and non -epld devices */
/* the endpoint is a socket that may be used */
void jumper_equivalent_pins (void)
{
char equiv_buff[MAXIDLEN];
equivalent_node_t *curr_ref;
equivalent_node_set_t *node_set;
socket_t *dev;
net_t *top_net, *current_net;
dev = socket_head;
while (dev)
{
/* any equivalent pins */
if (dev->equivalent_node_set)
{
#if defined DEBUG_EQUIV
Log (
LOG_GENERAL,
"-- Device %s has equivalent pins\n",
dev->identifier);
#endif
node_set = dev->equivalent_node_set;
while (node_set)
{
/* create a top level jumper name made out device ID
concatenated with current pin IDs */
sprintf (equiv_buff
, "E_%s", dev
->identifier
);
curr_ref = node_set->nodes;
while (curr_ref)
{
current_net = curr_ref->node->net;
/* if there is a net attached to the pin it is a routed
net.
only make the jumper if it is actually a usable net
for routing. */
if (current_net &&
IS_ROUTABLE (current_net->how_routed))
{
equiv_buff, curr_ref->node->identifier);
}
curr_ref = curr_ref->next;
}
/* printf("Making %s\n",equiv_buff); */
top_net = find_net (&routed_list, Ident, equiv_buff, Create);
top_net->how_joined = Jumpered;
#if defined DEBUG_EQUIV
Log (LOG_GENERAL, "-- making jumper %s\n", equiv_buff);
#endif
curr_ref = node_set->nodes;
while (curr_ref)
{
current_net = curr_ref->node->net;
/* if there is a net attached to the pin it is a routed
net.
only make the jumper if it is actually a usable net
for routing. */
if (current_net &&
IS_ROUTABLE (current_net->how_routed))
{
#if defined DEBUG_EQUIV
Log (
LOG_GENERAL,
"-- connecting net %s ( pin %s(%s))\n",
curr_ref->node->net->identifier,
dev->identifier,
curr_ref->node->identifier);
#endif
current_net->external_node =
NULL; /* jumpered by net name */
transfer_net_to_subnet (
&routed_list, top_net, current_net);
}
curr_ref = curr_ref->next;
}
/* no child nets or jumper joins only one subnet : delete
* jumper */
if (!top_net->subnets || !top_net->subnets->joined_nets)
disconnect_jumper (&routed_list, top_net);
node_set = node_set->next;
}
}
dev = dev->next;
}
}