/*
* $Id: statistics.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $
*
* $Log: statistics.c,v $
* Revision 1.1.1.1 2003/11/04 23:34:57 mjames
* Imported into local repositrory
*
* Revision 1.9 2002/01/16 11:22:49 mjames
* database.h header file is read in first as it undefined DLL stuff irrelevant
* to HPUX
*
* Revision 1.8 2002/01/15 12:33:14 mjames
* removed unused variable
*
* Revision 1.7 2001/10/31 22:20:18 mjames
* Tidying up problematical comments caused by CVS
* 'intelligent' comment guessing
*
* Revision 1.6 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.5 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.4 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.3 2001/09/25 23:15:22 mjames
* Converted wildcards to use proper regexp pattern match library
*
* 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.37 2000/10/12 14:27:48 14:27:48 mjames (Mike James)
* changed listing vhdl signals to expand expressions
* until a constant is located
*
* Revision 1.36 2000/10/04 10:37:10 10:37:10 mjames (Mike James)
* Modified for Vertical2 : support COMPONENTS and SIGNALS
*
* Revision 1.36 2000/10/04 10:37:10 10:37:10 mjames (Mike James)
* Part of Release PSAVAT01
*
* Revision 1.35 2000/10/02 11:04:21 11:04:21 mjames (Mike James)
* new_vhdl
*
* Revision 1.34 2000/09/27 14:42:21 14:42:21 mjames (Mike James)
* Part of Release Sep_27_ST_2000
*
* Revision 1.33 2000/09/21 10:15:51 10:15:51 mjames (Mike James)
* Part of Release Sep21Alpha
*
* Revision 1.32 2000/09/21 09:47:33 09:47:33 mjames (Mike James)
* Corrected <cr> problem
*
* Revision 1.31 2000/08/25 09:57:17 09:57:17 mjames (Mike James)
* Part of Release Aug25_alpha
*
* Revision 1.30 2000/08/16 08:57:33 08:57:33 mjames (Mike James)
* Part of Release CD01_Aug2000
*
* Revision 1.29 2000/08/14 14:45:14 14:45:14 mjames (Mike James)
* Part of Release Aug_14_2000
*
* Revision 1.28 2000/08/11 08:30:34 08:30:34 mjames (Mike James)
* Part of Release Aug_11_2000
*
* Revision 1.27 2000/08/09 10:31:50 10:31:50 mjames (Mike James)
* Part of Release Aug__9_2000
*
* Revision 1.26 2000/05/31 11:43:01 11:43:01 mjames (Mike James)
* Part of Release May_31_2000
*
* Revision 1.25 2000/05/08 17:01:40 17:01:40 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.24 2000/05/08 16:59:33 16:59:33 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.23 2000/05/08 16:57:10 16:57:10 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.22 2000/05/03 15:28:39 15:28:39 mjames (Mike James)
* Corrected abuse of null pointers
*
* Revision 1.21 2000/03/08 16:19:33 16:19:33 mjames (Mike James)
* New version including PC
*
* Revision 1.18 2000/01/20 15:58:51 15:58:51 mjames (Mike James)
* Part of Release R22
*
* Revision 1.17 99/12/22 11:15:31 11:15:31 mjames (Mike James)
* Part of Release Dec_22_1999
*
* Revision 1.16 99/06/25 14:35:52 14:35:52 mjames (Mike James)
* Added in reference to expression.h, but no changes made
* to the function of acfread yet.
*
* Revision 1.15 99/05/04 09:52:55 09:52:55 mjames (Mike James)
* General checkin
*
* Revision 1.14 98/03/16 11:39:55 11:39:55 mjames (Mike James)
* Altered XREF printout to use wildcards.
*
* Revision 1.13 98/02/11 11:27:25 11:27:25 mjames (Mike James)
* Checked in for version 6.2a
*
* Revision 1.12 97/04/23 08:43:26 08:43:26 mjames (Mike James)
* CHecked in for release rel23041997
*
* Revision 1.11 97/01/03 13:37:29 13:37:29 mjames (Mike James)
* Tidied up the ensure_reserved() function. Added in a flag to
* indicate that a net has been processed by ensure_reserved()
* And so is not in error for only having 0 or 1 nodes names (which is the
* case for a 1 or 2 node net that has been processed. One of the nodes will
* remain unnnamed and this will result in 0 or 1 nodes apparently in use
*
* Revision 1.10 96/12/23 15:15:34 15:15:34 mjames (Mike James)
* ?
*
* Revision 1.9 96/12/13 08:43:14 08:43:14 mjames (Mike James)
* Update to v5.1, added Write ID , exact routing
*
* Revision 1.8 96/08/06 13:38:57 13:38:57 mjames (Mike James)
* Added a count of nets with low numbers of nodes in the routed list.
*
* Revision 1.7 96/07/19 14:38:46 14:38:46 mjames (Mike James)
* Update to give to PRL
*
* Revision 1.6 1996/07/12 15:52:12 mjames
* Sorted out things like Alias and Jumpers
* Work Correctly
* Print COrrectly
*
* Revision 1.5 96/06/17 13:01:48 13:01:48 mjames (Mike James)
* Altered the printing of JUMPERED and ALIASED nets
* ,
*
* Revision 1.4 96/04/26 16:02:36 16:02:36 mjames (Mike James)
* Altered inside/outside determination of signal directions
*
* Revision 1.3 96/04/15 14:19:38 14:19:38 mjames (Mike James)
* Checkin before datatype printing
* modifications
*
* Revision 1.2 96/03/29 14:46:34 14:46:34 mjames (Mike James)
* Added VHDL netlist writing to the capabilities of ACFREAD
*
* Revision 1.1 96/03/26 07:47:46 07:47:46 mjames (Mike James)
* Initial revision
* */
/* The statistics module . This counts the connections between the chip and
other named chips. */
#include "statistics.h"
#include "chck_names.h"
#include "cmdlog.h"
#include "cmdparse.h"
#include "database.h"
#include "expression.h"
#include "generic.h"
#include "lx_support.h"
#include "sorting.h"
#include "vertcl_main.h"
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
static char IDstr[] = "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/statistics.c,v 1.1.1.1 "
"2003/11/04 23:34:57 mjames Exp $";
/* this procedure counts paths from a named socket to all other named
sockets. There are two wildcard options :
no wildcard : all sockets are listed
string* : any string beginning 'string'
* : all named sockets */
int count_paths (char *template)
{
socket_t *skt_p, *skt_try;
noderef_t *net_nodes;
node_t *skt_nodes;
net_t **list_member;
int rc;
char *pattern;
/* compile regular expression */
vert_regex_t *preg;
skt_p = socket_head;
/* clear all of the visit counters */
while (skt_p)
{
skt_p->named_in_use_cnt = skt_p->named_cnt = skt_p->routed_cnt =
skt_p->unrouted_cnt = 0;
skt_p = skt_p->next;
}
if (!ISNULLSTR (template))
{
pattern = template;
}
else
{
pattern = ".*";
}
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;
}
Log (
LOG_GENERAL,
"-- Listing xref for socket names '%s' --\n",
template ? template : "[ALL Sockets]");
skt_p = socket_head;
while (skt_p)
{
int found;
found = regexec (preg->preg, skt_p->name, 0, preg->regpatt, 0);
if (!found)
{
skt_nodes = skt_p->nodes;
/*
fprintf(f,"named = %p , routed = %p unrouted = %p\n",
&named_list,&routed_list,&unrouted_list);
*/
/* we have located the socket on the net . Let us now locate each net
*/
/* some nodes on a socket will be unrouted nodes on unrouted nets that
have now been resolved , and the unrouted net will have been deleted
. These have the property that node->net->list_ref = NULL */
while (skt_nodes)
{
net_t *ref_net = skt_nodes->net;
if (ref_net)
{
int high, low, width, net_high, net_low;
net_nodes = ref_net->nodes;
/* note the upper and lower bound of the bundle
* connected from this pin of this socket to the net.
* Also checking there is an associated VHDL type 4 May
* 2000 */
if (skt_nodes->vhdltype)
{
eval_vhdl_expression (
skt_nodes->vhdltype->expr,
&net_high,
&net_low);
}
else
{
net_low = 0;
net_high = 0;
}
/* which list is this net on */
list_member = ref_net->list_ref;
/* visit each node */
while (net_nodes)
{
node_t *n = net_nodes->node;
vhdl_t *vhdl = net_nodes->vhdltype;
int vhdl_high, vhdl_low;
if (vhdl)
{
/* to determine the intersection of the
* bundles, hence connection count :
* (15 downto 8) connected to (10
* downto 5) has intersection (10
* downto 8)
*/
if (vhdl->expr)
eval_vhdl_expression (
vhdl->expr,
&vhdl_high,
&vhdl_low);
else
{
vhdl_high = 0;
vhdl_low = 0;
}
/* use the lowest high bound of the
* node this net comes from */
high = vhdl_high > net_high
? net_high
: vhdl_high;
/* use the highest low bound of the
* node this net comes from */
low = vhdl_low < net_low ? net_low
: vhdl_low;
/* now get the number of wires in the
* bundle */
width = high - low + 1;
if (list_member == &named_list)
{
if (n->in_use)
n->socket
->named_in_use_cnt +=
width;
else
n->socket->named_cnt +=
width;
}
else if (list_member == &routed_list)
n->socket->routed_cnt += width;
else if (list_member == &unrouted_list)
n->socket->unrouted_cnt +=
width;
else if (list_member != NULL)
Log (
LOG_ERROR,
"# ERROR : Net %s is on "
"unknown list pointer=%p "
", net \n",
ref_net->name,
list_member);
}
net_nodes = net_nodes->next;
}
}
skt_nodes = skt_nodes->sktnext;
}
/* now have compiled a cross reference count */
skt_try = socket_head;
Log (
LOG_GENERAL, "-- Cross reference for socket '%s'\n", skt_p->name);
Log (
LOG_GENERAL,
"Name : Named&Used, Named, Routed,Unrouted\n");
skt_try = socket_head;
while (skt_try)
{
if (!ISNULLSTR (skt_try->name))
{
Log (
LOG_GENERAL,
"%16s : %5d, %5d, %5d, %5d\n",
skt_try->name,
skt_try->named_in_use_cnt,
skt_try->named_cnt,
skt_try->routed_cnt,
skt_try->unrouted_cnt);
}
skt_try->named_in_use_cnt = skt_try->named_cnt =
skt_try->routed_cnt = skt_try->unrouted_cnt = 0;
skt_try = skt_try->next;
}
}
skt_p = skt_p->next;
}
vert_regfree (&preg);
return OKCMD; /* success */
}
/* this procedure counts up and displays the number of nets with less than a certain
threshold number of nodes actually in use. */
void count_nets_with_few_nodes (int limit)
{
long lowcount = 0;
net_t *routed_net = named_list;
Log (
LOG_GENERAL,
"-- Checking for nets with less than or equal to %d nodes in use\n",
limit);
while (routed_net)
{
int nodecount = 0;
noderef_t *routed_nodes = routed_net->nodes;
while (routed_nodes)
{
/* node_t *cnode = routed_nodes->node; */
if (routed_nodes->node->net_assigned != 0)
nodecount++;
routed_nodes = routed_nodes->next;
}
/* turn off warning if low nodecount is due to ensure_reserved processing in
* routing.c */
if (nodecount <= limit && !routed_net->nodes_reserved)
{
Log (
LOG_GENERAL,
"-- Net '%s' (name '%s') has only %d node(s) in use\n",
routed_net->identifier,
routed_net->name,
nodecount);
lowcount++;
}
routed_net = routed_net->next;
}
Log (LOG_GENERAL, "-- Found %d nets with less than %d nodes used\n", lowcount, limit);
}
/* keep some cc's happy */
void statistics_waste (void)
{
char *s = IDstr;
s = s;
}