Entee de loon.. attend abv...
CVSe ----------------------------------------------------------------------
This commit is contained in:
parent
49bf97be1b
commit
3fc2bb448b
|
@ -0,0 +1,3 @@
|
||||||
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
|
SUBDIRS = doc src
|
|
@ -0,0 +1,33 @@
|
||||||
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
AC_INIT(src/lon_main.c)
|
||||||
|
|
||||||
|
LOON_MAJOR_VERSION=1
|
||||||
|
LOON_MINOR_VERSION=3
|
||||||
|
LOON_VERSION=$LOON_MAJOR_VERSION.$LOON_MINOR_VERSION
|
||||||
|
|
||||||
|
AC_SUBST(LOON_MAJOR_VERSION)
|
||||||
|
AC_SUBST(LOON_MINOR_VERSION)
|
||||||
|
AC_SUBST(LOON_VERSION)
|
||||||
|
|
||||||
|
# For automake.
|
||||||
|
VERSION=$LOON_VERSION
|
||||||
|
PACKAGE=loon
|
||||||
|
|
||||||
|
dnl Initialize automake stuff
|
||||||
|
AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
|
||||||
|
|
||||||
|
dnl Checks for programs.
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_MAKE_SET
|
||||||
|
|
||||||
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_C_CONST
|
||||||
|
|
||||||
|
dnl path for libs and includes
|
||||||
|
AM_ALLIANCE
|
||||||
|
|
||||||
|
AC_OUTPUT([
|
||||||
|
Makefile
|
||||||
|
doc/Makefile
|
||||||
|
src/Makefile
|
||||||
|
])
|
|
@ -0,0 +1,4 @@
|
||||||
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
|
man_MANS = loon.1
|
||||||
|
EXTRA_DIST = $(man_MANS)
|
|
@ -0,0 +1,131 @@
|
||||||
|
.\"
|
||||||
|
.\" This file is part of the Alliance CAD System
|
||||||
|
.\" Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
.\" Universite Pierre et Marie Curie
|
||||||
|
.\"
|
||||||
|
.\" Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
.\" E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
.\"
|
||||||
|
.\" This progam is free software; you can redistribute it and/or modify it
|
||||||
|
.\" under the terms of the GNU General Public License as published by the
|
||||||
|
.\" Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
.\" option) any later version.
|
||||||
|
.\"
|
||||||
|
.\" Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
.\" useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
.\" Public License for more details.
|
||||||
|
.\"
|
||||||
|
.\" You should have received a copy of the GNU General Public License along
|
||||||
|
.\" with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
.\"
|
||||||
|
.\"
|
||||||
|
.\" Tool : Man pages
|
||||||
|
.\" Date : 1991,92,2000
|
||||||
|
.\" Author : Luc Burgun, Pascale Allegre, Nathalie Dictus
|
||||||
|
.\" Modified by Czo <Olivier.Sirol@lip6.fr> 1996,97
|
||||||
|
.\" Modified by francois Donnet 2000
|
||||||
|
.\"
|
||||||
|
.\"
|
||||||
|
.\"
|
||||||
|
.\"
|
||||||
|
.\"
|
||||||
|
.pl -.4
|
||||||
|
.TH LOON 1 "Sept 01 2000" "ASIM/LIP6" "CAO\-VLSI Reference Manual"
|
||||||
|
.SH NAME
|
||||||
|
.TP
|
||||||
|
LooN \- Light optimizing on Nets.
|
||||||
|
|
||||||
|
|
||||||
|
.so man1/alc_origin.1
|
||||||
|
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.TP
|
||||||
|
\f4loon\fP [-hmxlo] \fIinput_file\fP \fIoutput_file\fP [\fIlax_file\fP]
|
||||||
|
.br
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.br
|
||||||
|
\f4loon\fP is a CAD tool that permits to remove fanout problems within a gates netlist and to optimize the delay. The netlist can be hierarchical and is flattened if necessary. \f4loon\fP run in batch mode and a parameter file can be used (see man \f4lax\fP) to parametrize optimization by adding informations on outputs (fanin), inputs (fanout, delay) and by setting general parameters such as optimization level.
|
||||||
|
\f4loon\fP permits to compute delays of gates in the netlist and gives the critical path in the netlist. The global optimization of \f4loon\fP performs gate repowering to decrease the critical path delay. No buffers are inserted at this state of development of \f4loon\fP.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
.br
|
||||||
|
\f4 lax Parameter file description\fP
|
||||||
|
.br
|
||||||
|
The lax file is common with other logic synthesis tools and is used
|
||||||
|
for driving the synthesis process.
|
||||||
|
See \f4lax\fP(5) manual for more detail.
|
||||||
|
|
||||||
|
.br
|
||||||
|
\f4lax\fP uses a lot of parameters to guide every step of the synthesis process.
|
||||||
|
Some parameters are globally used (for example, \fIoptimization level\fP whereas others are specifically used (\f4load capacitance\fP for the netlist optimization only).
|
||||||
|
Here is the default lax file (see the user's manual for further information about the syntax of the '.lax' file):
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
Optimization mode = 2 (50% area - 50% delay)
|
||||||
|
.br
|
||||||
|
Input impedance = 0
|
||||||
|
.br
|
||||||
|
Output capacitance = 0
|
||||||
|
.br
|
||||||
|
Delayed input = none
|
||||||
|
.br
|
||||||
|
Auxiliary signal saved = none
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
.SH OPTION
|
||||||
|
.TP 10
|
||||||
|
\f4\-h\fP
|
||||||
|
Help mode. Displays possible uses of \f4loon\fP.
|
||||||
|
.TP 10
|
||||||
|
\f4\-o input_file\fP
|
||||||
|
Overwrites the source file if no \fIoutput_file\fP is given. This can be usefull if you don't want several netlist files.
|
||||||
|
.TP 10
|
||||||
|
\f4\-m optim_mode\fP
|
||||||
|
Optimization mode. Can be defined in lax file, it's only a shortcut to define it on command line. This mode number has an array defined between \fI0\fP and \fI4\fP. It indicates the way of optimization the user wants. If \fI0\fP is chosen, the circuit area will be improved. On the other hand, \fI4\fP will improve circuit delays. \fI2\fP is a medium value for optimization.
|
||||||
|
.TP 10
|
||||||
|
\f4\-x xsch_mode\fP
|
||||||
|
Generate a '.xsc' file. It is a color map for each signals contained in \fIoutput_file\fP network. This file is used by \f4xsch\fP to view the netlist. By choosing level 0 or 1 for xsch_mode, you can color respectively the critical path or all signals with delay graduation.
|
||||||
|
.TP 10
|
||||||
|
\f4\-l lax_file\fP
|
||||||
|
Just another way to show explicitely the \f4LAX\fP parameter file name.
|
||||||
|
.br
|
||||||
|
|
||||||
|
.SH ENVIRONMENT VARIABLES
|
||||||
|
.br
|
||||||
|
The following environment variables have to be set before using \f4loon\fP :
|
||||||
|
.HP
|
||||||
|
.ti 7
|
||||||
|
\fIMBK_CATA_LIB\fP gives the auxiliary paths of the directories of input files (behavioural description).
|
||||||
|
.HP
|
||||||
|
.ti 7
|
||||||
|
\fIMBK_TARGET_LIB\fP gives the path (single) of the directory of the selected standard cell library.
|
||||||
|
.HP
|
||||||
|
.ti 7
|
||||||
|
\fIMBK_IN_LO\fP gives the input format of the structural description.
|
||||||
|
.HP
|
||||||
|
.ti 7
|
||||||
|
\fIMBK_OUT_LO\fP gives the output format of the structural description.
|
||||||
|
|
||||||
|
|
||||||
|
.SH EXAMPLE
|
||||||
|
.br
|
||||||
|
You can call \f4loon\fP as follows :
|
||||||
|
.br
|
||||||
|
.br
|
||||||
|
loon alu alu_loon
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.br
|
||||||
|
loon(1), boog(1), boom(1), lax(1), vbe(1), scmap(1), bop(1), glop(1), c4map(1), xlmap(1), proof(1), yagle(1), asimut(1), vhdl(5), scr(1), sclib(1), sxlib(1).
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
.so man1/alc_bug_report.1
|
|
@ -0,0 +1,23 @@
|
||||||
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
|
bin_PROGRAMS = loon
|
||||||
|
|
||||||
|
loon_LDADD = @LIBS@ \
|
||||||
|
-lAbv -lAbe -lAbt -lMlu -lMcl -lMal -lMsl -lMhl -lMel -lMvl -lMgl -lRcn -lMlo -lBdd -lAbl -lAut -lMut
|
||||||
|
|
||||||
|
loon_SOURCES = \
|
||||||
|
lon_lax_param.c lon_lib_utils.c lon_optim_capa.h \
|
||||||
|
lon_lax_param.h lon_lib_utils.h lon_optim_stats.c \
|
||||||
|
lon_lib_format.c lon_main.c lon_optim_stats.h \
|
||||||
|
lon_lib_format.h lon_normalize_DAG.c lon_signal_critical.c \
|
||||||
|
lon_lib_matching.c lon_normalize_DAG.h lon_signal_critical.h \
|
||||||
|
lon_lib_matching.h lon_normalize_message.c lon_signal_name.c \
|
||||||
|
lon_lib_negativ.c lon_normalize_message.h lon_signal_name.h \
|
||||||
|
lon_lib_negativ.h lon_normalize_power.c lon_signal_netlist.c \
|
||||||
|
lon_lib_permute.c lon_normalize_power.h lon_signal_netlist.h \
|
||||||
|
lon_lib_permute.h lon_normalize_register.c lon_signal_utils.c \
|
||||||
|
lon_lib_reader.c lon_normalize_register.h lon_signal_utils.h \
|
||||||
|
lon_lib_reader.h lon_normalize_simplify.c lon_xsch_driver.c \
|
||||||
|
lon_lib_specifications.c lon_normalize_simplify.h lon_xsch_driver.h \
|
||||||
|
lon_lib_specifications.h lon_optim_capa.c
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : SCmap and Loon - parameter file
|
||||||
|
* Date : 1991,92
|
||||||
|
* Author : Luc Burgun
|
||||||
|
* Modified by Czo <Olivier.Sirol@lip6.fr> 1996,97
|
||||||
|
* Modified: Francois Donnet 2000
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LAX_PARAM_H
|
||||||
|
#define LAX_PARAM_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*default and neutral value don't move them without looking*/
|
||||||
|
#define OPTIM_DELAY0 0 /*optimization in area*/
|
||||||
|
#define OPTIM_DELAY1 1
|
||||||
|
#define OPTIM_DELAY2 2 /* 50% delay - 50% area */
|
||||||
|
#define OPTIM_DELAY3 3
|
||||||
|
#define OPTIM_DELAY4 4 /*optimization in delay*/
|
||||||
|
#define DEFAULT_OPTIM OPTIM_DELAY2 /*optimization 50% for delay by default*/
|
||||||
|
|
||||||
|
/*physical values*/
|
||||||
|
#define DEFAULT_DELAY 0 /*pico second exp-12 s. (around 200)*/
|
||||||
|
#define DEFAULT_CAPACITANCE 0 /*pico Farad exp-12 F. (around 0.009)*/
|
||||||
|
#define DEFAULT_IMPEDANCE 0 /*Ohm (around 1620)*/
|
||||||
|
#define DEFAULT_BUFFER 0 /*num of buffer to put after input*/
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* parse the .lax file and save the internal caracteristics */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void parsefilelax __P ((char *filename));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* set default caracteristics if no file is given */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void defaultlax __P ((int mode_optim));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* save the internal caracteristics in file */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void savefilelax __P ((char *filename));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the delay (in ps exp-12) of name for an input in lax file */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double getdelaylax __P ((char *name));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the impedance(R in Ohm) of name for an input in lax file */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double getimpedancelax __P ((char *name));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the fanout(C in pF exp-12) of name for an output in lax file */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double getcapacitancelax __P ((char *name));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the number of buffers to put after input in lax file */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern int getbufferlax __P ((char *name));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return 1 if the internal signal shouldn't be erased */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern int signalsavelax __P ((char *signame));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the optim param in lax file */
|
||||||
|
/* 0,1: optimize in area */
|
||||||
|
/* 3,4: optimize in delay */
|
||||||
|
/* 2: middle */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern int getoptimlax __P (());
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return 1 if lax matches with lofig */
|
||||||
|
/* look if all referenced names are in lofig */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern int coherencelax __P ((lofig_list* lofig));
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,221 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - format library cells
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <mut.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include <mlu.h>
|
||||||
|
#include <abv.h>
|
||||||
|
#include "lon_lib_format.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return 1 if input is found in abl */
|
||||||
|
/******************************************************************************/
|
||||||
|
static int is_input_used(char* input, chain_list* abl)
|
||||||
|
{
|
||||||
|
if (!abl) return 0;
|
||||||
|
|
||||||
|
if (ABL_ATOM(abl)) {
|
||||||
|
char *value=ABL_ATOM_VALUE(abl);
|
||||||
|
/*constant*/
|
||||||
|
if (value==getablatomzero() || value==getablatomone()
|
||||||
|
|| value==getablatomtristate() || value==getablatomdc()) return 0;
|
||||||
|
if (value==input) return 1;
|
||||||
|
return 0; /*not found*/
|
||||||
|
}
|
||||||
|
|
||||||
|
for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) {
|
||||||
|
if (is_input_used(input,ABL_CAR(abl))) return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /*not found*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* seek if all inputs are used in abl */
|
||||||
|
/******************************************************************************/
|
||||||
|
static int used_inputs(befig_list* befig, chain_list* abl1, chain_list* abl2)
|
||||||
|
{
|
||||||
|
bepor_list* bepor;
|
||||||
|
|
||||||
|
/*all inputs should be used*/
|
||||||
|
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
|
||||||
|
/*only input*/
|
||||||
|
if (bepor->DIRECTION!=IN && bepor->DIRECTION!=INOUT
|
||||||
|
&& bepor->DIRECTION!=TRANSCV) continue;
|
||||||
|
if (!isvdd(bepor->NAME) && !isvss(bepor->NAME)) {
|
||||||
|
if (!is_input_used(bepor->NAME,abl1)
|
||||||
|
&& !is_input_used(bepor->NAME,abl2)) {
|
||||||
|
fprintf(stderr,"BEH: %s input unused\n",bepor->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;/*all used*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return 1 if format is ok */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int format_cell(befig_list* befig)
|
||||||
|
{
|
||||||
|
/*internal signal forbidden*/
|
||||||
|
if (befig->BEAUX) return 0;
|
||||||
|
|
||||||
|
if (befig->BEREG) {
|
||||||
|
/*only one register*/
|
||||||
|
if (befig->BEREG->NEXT || befig->BEBUS || befig->BEBUX) return 0;
|
||||||
|
/*only one condition*/
|
||||||
|
if (!befig->BEREG->BIABL || befig->BEREG->BIABL->NEXT) return 0;
|
||||||
|
/*one ouput*/
|
||||||
|
if (!befig->BEOUT || befig->BEOUT->NEXT) return 0;
|
||||||
|
/* forbid logic on output */
|
||||||
|
if (!ABL_ATOM(befig->BEOUT->ABL)) {
|
||||||
|
chain_list* abl;
|
||||||
|
abl=befig->BEOUT->ABL;
|
||||||
|
if (ABL_OPER(abl)!=ABL_NOT) return 0;
|
||||||
|
abl=ABL_CADR(abl);
|
||||||
|
if (!ABL_ATOM(abl) || ABL_ATOM_VALUE(abl)!=befig->BEREG->NAME)return 0;
|
||||||
|
/* output <= not reg; -> move not to register value*/
|
||||||
|
freeablexpr(befig->BEOUT->ABL);
|
||||||
|
befig->BEOUT->ABL=createablatom(befig->BEREG->NAME);
|
||||||
|
befig->BEREG->BIABL->VALABL=simpablexpr(
|
||||||
|
createablnotexpr(befig->BEREG->BIABL->VALABL));
|
||||||
|
}
|
||||||
|
return used_inputs(befig,befig->BEREG->BIABL->CNDABL,
|
||||||
|
befig->BEREG->BIABL->VALABL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (befig->BEBUS) {
|
||||||
|
/*only one bus*/
|
||||||
|
if (befig->BEBUS->NEXT || befig->BEREG || befig->BEBUX) return 0;
|
||||||
|
/*only one condition*/
|
||||||
|
if (!befig->BEBUS->BIABL || befig->BEBUS->BIABL->NEXT) return 0;
|
||||||
|
/*one ouput: bebus*/
|
||||||
|
if (befig->BEOUT) return 0;
|
||||||
|
return used_inputs(befig,befig->BEBUS->BIABL->CNDABL,
|
||||||
|
befig->BEBUS->BIABL->VALABL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (befig->BEBUX) {
|
||||||
|
/*only one internal bus*/
|
||||||
|
if (befig->BEBUX->NEXT || befig->BEREG || befig->BEBUS) return 0;
|
||||||
|
/*only one condition*/
|
||||||
|
if (!befig->BEBUX->BIABL || befig->BEBUX->BIABL->NEXT) return 0;
|
||||||
|
/*one ouput: beout*/
|
||||||
|
if (!befig->BEOUT || befig->BEOUT->NEXT) return 0;
|
||||||
|
/* forbid logic on output */
|
||||||
|
if (!ABL_ATOM(befig->BEOUT->ABL)) {
|
||||||
|
chain_list* abl;
|
||||||
|
abl=befig->BEOUT->ABL;
|
||||||
|
if (ABL_OPER(abl)!=ABL_NOT) return 0;
|
||||||
|
abl=ABL_CADR(abl);
|
||||||
|
if (!ABL_ATOM(abl) || ABL_ATOM_VALUE(abl)!=befig->BEBUX->NAME)return 0;
|
||||||
|
/* output <= not bus; */
|
||||||
|
freeablexpr(befig->BEOUT->ABL);
|
||||||
|
befig->BEOUT->ABL=createablatom(befig->BEBUX->NAME);
|
||||||
|
befig->BEBUX->BIABL->VALABL=simpablexpr(
|
||||||
|
createablnotexpr(befig->BEBUX->BIABL->VALABL));
|
||||||
|
}
|
||||||
|
/*normalize befig -> move bebux to bebus */
|
||||||
|
befig->BEBUS=beh_addbebus(befig->BEBUS,befig->BEOUT->NAME,
|
||||||
|
befig->BEBUX->BIABL,NULL,'M'/*mux_bit instead of wor_bit'W'*/);
|
||||||
|
befig->BEBUX->BIABL=NULL; /*protect from beh_frebebux()*/
|
||||||
|
beh_frebebux(befig->BEBUX);
|
||||||
|
freeablexpr(befig->BEOUT->ABL);
|
||||||
|
beh_frebeout(befig->BEOUT);
|
||||||
|
befig->BEBUX=NULL;
|
||||||
|
befig->BEOUT=NULL;
|
||||||
|
return used_inputs(befig,befig->BEBUS->BIABL->CNDABL,
|
||||||
|
befig->BEBUS->BIABL->VALABL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (befig->BEOUT) {
|
||||||
|
/*one ouput: beout*/
|
||||||
|
if (!befig->BEOUT || befig->BEOUT->NEXT) return 0;
|
||||||
|
return used_inputs(befig,befig->BEOUT->ABL,NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*illegal befig*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*put the locon of the lofig associated to the befig */
|
||||||
|
/*in the same order than bepor */
|
||||||
|
/* return 0 if no error */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int sortbepor(befig_list* befig)
|
||||||
|
{
|
||||||
|
lofig_list* lofig;
|
||||||
|
bepor_list* bepor;
|
||||||
|
locon_list* locon, *pred;
|
||||||
|
|
||||||
|
lofig=getlofig(befig->NAME,'P');
|
||||||
|
|
||||||
|
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
|
||||||
|
|
||||||
|
pred=NULL;
|
||||||
|
for (locon=lofig->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (bepor->NAME==locon->NAME) {
|
||||||
|
/*disconnect*/
|
||||||
|
if (pred) pred->NEXT=locon->NEXT;
|
||||||
|
else lofig->LOCON=locon->NEXT;
|
||||||
|
/*reconnect*/
|
||||||
|
locon->NEXT=lofig->LOCON;
|
||||||
|
lofig->LOCON=locon;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pred=locon;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!locon) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"BEH: mismatch with %s.al for cell %s.vbe on port %s\n",
|
||||||
|
befig->NAME, befig->NAME, bepor->NAME);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lofig->LOCON=(locon_list*) reverse((chain_list*) lofig->LOCON);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - format library cells
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LIB_FORMAT_H
|
||||||
|
#define LIB_FORMAT_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return 1 if format is ok */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int format_cell __P ((befig_list* befig));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*put the locon of the lofig associated to the befig */
|
||||||
|
/*in the same order than bepor */
|
||||||
|
/* return 0 if no error */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int sortbepor __P ((befig_list* befig));
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,171 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - pattern matching between cells
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <aut.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include "lon_lib_matching.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*size of memory block*/
|
||||||
|
#define BLOCK 256
|
||||||
|
|
||||||
|
static authtable* HTABLE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return 0, if there is already a variable with pattern */
|
||||||
|
/******************************************************************************/
|
||||||
|
static int relation_between(chain_list* expr, char* pattern)
|
||||||
|
{
|
||||||
|
authelem *elem;
|
||||||
|
|
||||||
|
elem=searchauthelem(HTABLE,pattern);
|
||||||
|
if (elem) {
|
||||||
|
chain_list* old_abl=(chain_list*)elem->VALUE;
|
||||||
|
if (ABL_ATOM(old_abl) && ABL_ATOM(expr)
|
||||||
|
&& ABL_ATOM_VALUE(old_abl)==ABL_ATOM_VALUE(expr)) return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
addauthelem(HTABLE, pattern,(int)expr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Pattern matching between an expr and a pattern. Return true if expr has */
|
||||||
|
/* the same operators and in the same order than pattern */
|
||||||
|
/* '1' , '0' , 'd' and 'z' are also checked if matched */
|
||||||
|
/****************************************************************************/
|
||||||
|
static int loc_pattern_matching(chain_list* expr, chain_list* pattern)
|
||||||
|
{
|
||||||
|
if (!expr || !pattern) {
|
||||||
|
fprintf(stderr,"loc_pattern_matching: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*pattern is an atom*/
|
||||||
|
if (ABL_ATOM (pattern)) {
|
||||||
|
/*constants MUST match*/
|
||||||
|
if (ABL_ATOM_VALUE(pattern)==getablatomone()) {
|
||||||
|
if (ABL_ATOM(expr) && ABL_ATOM_VALUE(expr)==getablatomone()) return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
if (ABL_ATOM_VALUE(pattern)==getablatomzero()) {
|
||||||
|
if (ABL_ATOM(expr) && ABL_ATOM_VALUE(expr)==getablatomzero()) return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
if (ABL_ATOM_VALUE(pattern)==getablatomdc() /* 'd' */) {
|
||||||
|
if (ABL_ATOM(expr) && ABL_ATOM_VALUE(expr)==getablatomdc()) return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
if (ABL_ATOM_VALUE(pattern)==getablatomtristate() /* 'z' */) {
|
||||||
|
if (ABL_ATOM(expr) && ABL_ATOM_VALUE(expr)==getablatomtristate())
|
||||||
|
return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
return relation_between(expr,ABL_ATOM_VALUE(pattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pattern isn't an atom and expr is*/
|
||||||
|
if (ABL_ATOM (expr)) return 0;
|
||||||
|
|
||||||
|
/* not the same oper */
|
||||||
|
if (ABL_OPER (expr) != ABL_OPER (pattern)) return 0;
|
||||||
|
|
||||||
|
for (pattern = ABL_CDR(pattern); pattern&&expr; pattern=ABL_CDR(pattern)) {
|
||||||
|
expr = ABL_CDR(expr);
|
||||||
|
if (!expr) return 0;
|
||||||
|
if (!loc_pattern_matching(ABL_CAR (expr), ABL_CAR (pattern))) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Pattern matching between an expr and a pattern. Return true if expr has */
|
||||||
|
/* the same operators and in the same order than pattern */
|
||||||
|
/* '1' , '0' , 'd' and 'z' are also checked if matched */
|
||||||
|
/*quite slow comparison */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern int pattern_matching(chain_list* expr, chain_list* pattern)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!expr || !pattern) {
|
||||||
|
fprintf(stderr,"pattern_matching: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
HTABLE=createauthtable (BLOCK);
|
||||||
|
|
||||||
|
ret=loc_pattern_matching(expr,pattern);
|
||||||
|
|
||||||
|
/*free table*/
|
||||||
|
destroyauthtable(HTABLE);
|
||||||
|
HTABLE=NULL;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* return 1 if befig1 and befig2 are strictly identical */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern int compare_befig(befig_list* befig1, befig_list* befig2)
|
||||||
|
{
|
||||||
|
if (befig1->BEBUS) {
|
||||||
|
if (!befig2->BEBUS) return 0;
|
||||||
|
return isablequalexpr(befig1->BEBUS->BIABL->VALABL,befig2->BEBUS->BIABL->VALABL) && isablequalexpr(befig1->BEBUS->BIABL->CNDABL,befig2->BEBUS->BIABL->CNDABL);
|
||||||
|
}
|
||||||
|
else if (befig1->BEREG) {
|
||||||
|
if (!befig2->BEREG) return 0;
|
||||||
|
/*flip-flop or latch*/
|
||||||
|
if (getptype(befig1->BEREG->BIABL->USER,ABL_STABLE)!=getptype(befig2->BEREG->BIABL->USER,ABL_STABLE)) return 0;
|
||||||
|
return isablequalexpr(befig1->BEREG->BIABL->VALABL,befig2->BEREG->BIABL->VALABL) && isablequalexpr(befig1->BEREG->BIABL->CNDABL,befig2->BEREG->BIABL->CNDABL);
|
||||||
|
}
|
||||||
|
else if (befig1->BEOUT) {
|
||||||
|
if (!befig2->BEOUT) return 0;
|
||||||
|
return isablequalexpr(befig1->BEOUT->ABL,befig2->BEOUT->ABL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - pattern matching between cells
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LIB_MATCHING_H
|
||||||
|
#define LIB_MATCHING_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Pattern matching between an expr and a pattern. Return true if expr has */
|
||||||
|
/* the same operators and in the same order than pattern */
|
||||||
|
/* '1' , '0' , 'd' and 'z' are also checked if matched */
|
||||||
|
/*quite slow comparison */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern int pattern_matching __P ((chain_list* expr, chain_list* pattern));
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* return 1 if befig1 and befig2 are strictly identical */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern int compare_befig __P ((befig_list* befig1, befig_list* befig2));
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - negativ operands
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include "lon_lib_negativ.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* build a tree on negativ logic by propagation of NOT to the leaves */
|
||||||
|
/* negativ is set to 1 to return the opposite abl (also in negativ logic) */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern chain_list* inv_oper(chain_list* abl, int negativ)
|
||||||
|
{
|
||||||
|
chain_list* chain;
|
||||||
|
|
||||||
|
if (ABL_ATOM(abl)) {
|
||||||
|
if (ABL_ATOM_VALUE(abl)==getablatomzero()) {
|
||||||
|
if (negativ) ABL_ATOM_VALUE(abl)=getablatomone();
|
||||||
|
}
|
||||||
|
else if (ABL_ATOM_VALUE(abl)==getablatomone()) {
|
||||||
|
if (negativ) ABL_ATOM_VALUE(abl)=getablatomzero();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (negativ) {
|
||||||
|
abl=createablnotexpr(abl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return abl;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ABL_OPER(abl)) {
|
||||||
|
case ABL_AND:
|
||||||
|
if (negativ) ABL_OPER(abl)=ABL_NAND;
|
||||||
|
else ABL_OPER(abl)=ABL_NOR;
|
||||||
|
negativ=!negativ;
|
||||||
|
break;
|
||||||
|
case ABL_NAND:
|
||||||
|
if (negativ) ABL_OPER(abl)=ABL_NOR;
|
||||||
|
else ABL_OPER(abl)=ABL_NAND;
|
||||||
|
break;
|
||||||
|
case ABL_OR:
|
||||||
|
if (negativ) ABL_OPER(abl)=ABL_NOR;
|
||||||
|
else ABL_OPER(abl)=ABL_NAND;
|
||||||
|
negativ=!negativ;
|
||||||
|
break;
|
||||||
|
case ABL_NOR:
|
||||||
|
if (negativ) ABL_OPER(abl)=ABL_NAND;
|
||||||
|
else ABL_OPER(abl)=ABL_NOR;
|
||||||
|
break;
|
||||||
|
case ABL_XOR:
|
||||||
|
if (negativ) ABL_OPER(abl)=ABL_NXOR;
|
||||||
|
negativ=0;
|
||||||
|
/*nothing to do: same size XOR and NXOR*/
|
||||||
|
break;
|
||||||
|
case ABL_NXOR:
|
||||||
|
if (negativ) ABL_OPER(abl)=ABL_XOR;
|
||||||
|
negativ=0;
|
||||||
|
/*nothing to do*/
|
||||||
|
break;
|
||||||
|
case ABL_NOT: /*erase NOT*/
|
||||||
|
chain=abl;
|
||||||
|
abl=inv_oper(ABL_CADR(abl),!negativ);
|
||||||
|
freechain(chain);
|
||||||
|
return abl;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"inv_oper: unknown operator %ld\n",ABL_OPER(abl));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
|
||||||
|
ABL_CAR(chain)=inv_oper(ABL_CAR(chain),negativ);
|
||||||
|
}
|
||||||
|
|
||||||
|
return abl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*return the abl in negativ logic */
|
||||||
|
/*we need 2 levels minimum of operator to invert an abl */
|
||||||
|
/*if only 1 level or neither odd nor even level return an unchanged abl */
|
||||||
|
/* minimize NOT operators number */
|
||||||
|
/*parameter is deleted */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern chain_list* build_negativ(chain_list* abl)
|
||||||
|
{
|
||||||
|
int to_inv=0; /*leaf to change*/
|
||||||
|
int to_let=0; /*leaf to let like this*/
|
||||||
|
chain_list *leaf, *chain;
|
||||||
|
|
||||||
|
if (ABL_ATOM(abl)) return abl;
|
||||||
|
/*NOT special case try to erase it*/
|
||||||
|
if (ABL_OPER(abl)==ABL_NOT) {
|
||||||
|
/*at the end, nothing to do*/
|
||||||
|
if (ABL_ATOM(ABL_CADR(abl))) return abl;
|
||||||
|
/*propagate inverters to the leaves*/
|
||||||
|
abl=inv_oper(abl,0);
|
||||||
|
/*abl has changed, try again*/
|
||||||
|
return build_negativ(abl);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
|
||||||
|
ABL_CAR(chain)=build_negativ(ABL_CAR(chain));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
|
||||||
|
leaf=ABL_CAR(chain);
|
||||||
|
if (ABL_ATOM(leaf)) {
|
||||||
|
/*constant undifferent*/
|
||||||
|
if (ABL_ATOM_VALUE(leaf)!=getablatomzero()
|
||||||
|
&& ABL_ATOM_VALUE(leaf)!=getablatomone()) to_let++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (ABL_OPER(leaf)) {
|
||||||
|
case ABL_AND: case ABL_OR: case ABL_NOT: to_inv++; break;
|
||||||
|
case ABL_NAND: case ABL_NOR: to_let++; break;
|
||||||
|
case ABL_XOR: case ABL_NXOR: /*undifferent*/ break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"inv_oper: oper %ld unknown\n",ABL_OPER(leaf));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*no gain, do not change*/
|
||||||
|
if (to_let>to_inv) return abl;
|
||||||
|
else if (to_let==to_inv) {
|
||||||
|
switch (ABL_OPER(abl)) {
|
||||||
|
/*no advantage to invert*/
|
||||||
|
case ABL_NAND: case ABL_NOR: case ABL_NXOR: case ABL_XOR: return abl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
|
||||||
|
leaf=ABL_CAR(chain);
|
||||||
|
if (ABL_ATOM(leaf)) {
|
||||||
|
/*constant undifferent*/
|
||||||
|
if (ABL_ATOM_VALUE(leaf)==getablatomzero())
|
||||||
|
ABL_ATOM_VALUE(leaf)=getablatomone();
|
||||||
|
else if (ABL_ATOM_VALUE(leaf)==getablatomone())
|
||||||
|
ABL_ATOM_VALUE(leaf)=getablatomzero();
|
||||||
|
else {
|
||||||
|
ABL_CAR(chain)=createablnotexpr(ABL_CAR(chain));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (ABL_OPER(leaf)) {
|
||||||
|
case ABL_AND: ABL_OPER(leaf)=ABL_NAND; break;
|
||||||
|
case ABL_OR: ABL_OPER(leaf)=ABL_NOR; break;
|
||||||
|
case ABL_NAND: ABL_OPER(leaf)=ABL_AND; break;
|
||||||
|
case ABL_NOR: ABL_OPER(leaf)=ABL_OR; break;
|
||||||
|
case ABL_XOR: ABL_OPER(leaf)=ABL_NXOR; break;
|
||||||
|
case ABL_NXOR: ABL_OPER(leaf)=ABL_XOR; break;
|
||||||
|
case ABL_NOT:
|
||||||
|
ABL_CAR(chain)=ABL_CADR(leaf);
|
||||||
|
freechain(leaf);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"inv_oper: oper %ld unknown\n",ABL_OPER(leaf));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ABL_OPER(abl)) {
|
||||||
|
case ABL_AND: ABL_OPER(abl)=ABL_NOR; break;
|
||||||
|
case ABL_OR: ABL_OPER(abl)=ABL_NAND; break;
|
||||||
|
case ABL_NAND: ABL_OPER(abl)=ABL_OR; break;
|
||||||
|
case ABL_NOR: ABL_OPER(abl)=ABL_AND; break;
|
||||||
|
case ABL_XOR: ABL_OPER(abl)=ABL_NXOR; break;
|
||||||
|
case ABL_NXOR: ABL_OPER(abl)=ABL_XOR; break;
|
||||||
|
case ABL_NOT:
|
||||||
|
chain=abl;
|
||||||
|
abl=ABL_CADR(abl);
|
||||||
|
freechain(chain);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"inv_oper: oper %ld unknown\n",ABL_OPER(leaf));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return abl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - negativ operands
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LIB_NEGATIV_H
|
||||||
|
#define LIB_NEGATIV_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* build a tree on negativ logic by propagation of NOT to the leaves */
|
||||||
|
/* negativ is set to 1 to return the opposite abl (also in negativ logic) */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern chain_list* inv_oper __P ((chain_list* abl, int negativ));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*return the abl in negativ logic */
|
||||||
|
/*we need 2 levels minimum of operator to invert an abl */
|
||||||
|
/*if only 1 level or neither odd nor even level return an unchanged abl */
|
||||||
|
/*parameter is deleted */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern chain_list* build_negativ __P ((chain_list* abl));
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,324 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - tree permutations
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include <aut.h>
|
||||||
|
#include <bdd.h>
|
||||||
|
#include "lon_lib_matching.h"
|
||||||
|
#include "lon_lib_specifications.h"
|
||||||
|
#include "lon_lib_utils.h"
|
||||||
|
#include "lon_lib_permute.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*free a list of list */
|
||||||
|
/******************************************************************************/
|
||||||
|
static void freechainchain(chain_list* chainchain)
|
||||||
|
{
|
||||||
|
chain_list* chain;
|
||||||
|
|
||||||
|
for (chain=chainchain; chain; chain=chain->NEXT) {
|
||||||
|
freechain(chain->DATA);
|
||||||
|
}
|
||||||
|
freechain(chainchain);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* duplicate a list */
|
||||||
|
/******************************************************************************/
|
||||||
|
static chain_list* dupchain(chain_list* pthead)
|
||||||
|
{
|
||||||
|
chain_list *chain;
|
||||||
|
chain_list *pred = NULL;
|
||||||
|
chain_list *first = NULL;
|
||||||
|
|
||||||
|
if ( !pthead ) return NULL;
|
||||||
|
|
||||||
|
first = addchain( NULL, pthead->DATA );
|
||||||
|
pred = first;
|
||||||
|
|
||||||
|
for ( chain = pthead->NEXT; chain; chain = chain->NEXT )
|
||||||
|
{
|
||||||
|
ABL_CDR( pred ) = addchain( NULL, chain->DATA );
|
||||||
|
pred = ABL_CDR( pred );
|
||||||
|
}
|
||||||
|
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*return a list with data element put in all positions of elemchain */
|
||||||
|
/*result is add on top of head */
|
||||||
|
/******************************************************************************/
|
||||||
|
static chain_list *all_positions(chain_list* head, chain_list* elemchain, void* data)
|
||||||
|
{
|
||||||
|
chain_list *chain, *list_elem, *pred=NULL;
|
||||||
|
|
||||||
|
if (!elemchain) {
|
||||||
|
elemchain=addchain(NULL,data);
|
||||||
|
return addchain(head,elemchain);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*insert elem on a lower position*/
|
||||||
|
list_elem=all_positions(NULL,elemchain->NEXT,data);
|
||||||
|
|
||||||
|
/*add the first element of elemchain for the result*/
|
||||||
|
for (chain=list_elem; chain; chain=chain->NEXT) {
|
||||||
|
chain->DATA=addchain(chain->DATA,elemchain->DATA);
|
||||||
|
pred=chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*create a new element with elem placed in first*/
|
||||||
|
elemchain=addchain(dupchain(elemchain),data);
|
||||||
|
list_elem=addchain(list_elem,elemchain);
|
||||||
|
|
||||||
|
/*take in account the head*/
|
||||||
|
pred->NEXT=head;
|
||||||
|
|
||||||
|
return list_elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*permute all elements of elemchain and return the list of permutations */
|
||||||
|
/* result is add on the top of head */
|
||||||
|
/******************************************************************************/
|
||||||
|
static chain_list *swap(chain_list* head, chain_list* elemchain)
|
||||||
|
{
|
||||||
|
chain_list *chain, *list_elem, *swap_elem;
|
||||||
|
|
||||||
|
|
||||||
|
if (!elemchain) {
|
||||||
|
if (!head) return addchain(NULL,NULL);
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*return a list of all possibilities with the rest of elemchain*/
|
||||||
|
swap_elem=swap(NULL,elemchain->NEXT);
|
||||||
|
|
||||||
|
list_elem=head;
|
||||||
|
for (chain=swap_elem; chain; chain=chain->NEXT) {
|
||||||
|
/*insert new element in all positions*/
|
||||||
|
/*add it to final result*/
|
||||||
|
list_elem=all_positions(list_elem,chain->DATA,elemchain->DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*free mem*/
|
||||||
|
freechainchain(swap_elem);
|
||||||
|
|
||||||
|
return list_elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*for a list of variable port, return the list of permutations possible */
|
||||||
|
/*it takes in account possible permutation variables contained in group */
|
||||||
|
/*result is add on the top of head */
|
||||||
|
/******************************************************************************/
|
||||||
|
static chain_list* replace(chain_list* head, chain_list* port, chain_list* group)
|
||||||
|
{
|
||||||
|
long place;
|
||||||
|
chain_list *chain, *elem, *new_port, *port_aux;
|
||||||
|
ptype_list* order=NULL, *ptype;
|
||||||
|
char* name;
|
||||||
|
|
||||||
|
/*memorize group places in port*/
|
||||||
|
place=0;
|
||||||
|
for (port_aux=port; port_aux; port_aux=port_aux->NEXT) {
|
||||||
|
name=port_aux->DATA;
|
||||||
|
for (chain=group->DATA; chain; chain=chain->NEXT) {
|
||||||
|
if (chain->DATA==name) {
|
||||||
|
order=addptype(order,place,name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
place++;
|
||||||
|
}
|
||||||
|
|
||||||
|
order=(ptype_list*)reverse((chain_list*)order);
|
||||||
|
|
||||||
|
/*replace each time by the values of group*/
|
||||||
|
for ( ; group; group=group->NEXT) {
|
||||||
|
elem=group->DATA;
|
||||||
|
new_port=dupchain(port);
|
||||||
|
ptype=order;
|
||||||
|
place=0;
|
||||||
|
/*replace values*/
|
||||||
|
for (chain=new_port; chain&&ptype; chain=chain->NEXT) {
|
||||||
|
if (ptype->TYPE==place) {
|
||||||
|
chain->DATA=elem->DATA;
|
||||||
|
elem=elem->NEXT;
|
||||||
|
ptype=ptype->NEXT;
|
||||||
|
}
|
||||||
|
place++;
|
||||||
|
}
|
||||||
|
head=addchain(head,new_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
freeptype(order);
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the list of possible order for port */
|
||||||
|
/*it takes in account permutations group list groupchain */
|
||||||
|
/*do not use port after calling function */
|
||||||
|
/******************************************************************************/
|
||||||
|
static chain_list* compose(chain_list* port, chain_list* groupchain)
|
||||||
|
{
|
||||||
|
chain_list* res=NULL, *chain;
|
||||||
|
chain_list* portchain, *group_swap;
|
||||||
|
|
||||||
|
if (!groupchain) return addchain(NULL,port);
|
||||||
|
|
||||||
|
portchain=compose(port,groupchain->NEXT);
|
||||||
|
/*do permutations inside group and return a list of orders*/
|
||||||
|
group_swap=swap(NULL,groupchain->DATA);
|
||||||
|
|
||||||
|
/*add this group to precedent list of port*/
|
||||||
|
for (chain=portchain; chain; chain=chain->NEXT) {
|
||||||
|
port=chain->DATA;
|
||||||
|
res=replace(res,port,group_swap);
|
||||||
|
}
|
||||||
|
|
||||||
|
freechainchain(group_swap);
|
||||||
|
freechainchain(portchain);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return a list of list of variables whom a permutation lets abl unchanged */
|
||||||
|
/*add result on the top of head */
|
||||||
|
/******************************************************************************/
|
||||||
|
static chain_list* permute_variable(chain_list* head,chain_list* abl)
|
||||||
|
{
|
||||||
|
bddsystem *system;
|
||||||
|
bddcircuit *circuit;
|
||||||
|
bddassoc *assoc;
|
||||||
|
bddvar a_variable, b_variable;
|
||||||
|
bddnode *a_bdd, *b_bdd;
|
||||||
|
bddnode *bdd, *new;
|
||||||
|
chain_list *pred, *first, *second, *save;
|
||||||
|
|
||||||
|
|
||||||
|
system = createbddsystem( 100, 1000, 100, 50000 );
|
||||||
|
circuit = createbddcircuit( "permute_world", 10, 10, system );
|
||||||
|
assoc=addbddassoc(system);
|
||||||
|
|
||||||
|
bdd=addbddcircuitabl(circuit,abl);
|
||||||
|
|
||||||
|
for (first=getablexprsupport(abl,ABL_SUPPORT_CHAIN); first; ) {
|
||||||
|
head=addchain(head,first);
|
||||||
|
a_bdd = searchbddcircuitin( circuit, (char*) first->DATA );
|
||||||
|
a_variable = getbddvarbyindex( system, a_bdd->INDEX );
|
||||||
|
|
||||||
|
pred=first;
|
||||||
|
for (second=first->NEXT; second; second=pred->NEXT) {
|
||||||
|
b_bdd = searchbddcircuitin( circuit, (char*) second->DATA );
|
||||||
|
b_variable = getbddvarbyindex( system, b_bdd->INDEX );
|
||||||
|
|
||||||
|
/*create association to swap*/
|
||||||
|
addbddnodeassoc( system, assoc, b_variable, a_bdd );
|
||||||
|
addbddnodeassoc( system, assoc, a_variable, b_bdd );
|
||||||
|
/*permute a and b */
|
||||||
|
new = substbddnodeassoc( system, bdd, assoc );
|
||||||
|
|
||||||
|
/*if same function then a and b indifferent*/
|
||||||
|
if (bdd==new) {
|
||||||
|
/*remove*/
|
||||||
|
pred->NEXT=second->NEXT;
|
||||||
|
/*put on new list*/
|
||||||
|
second->NEXT=head->DATA;
|
||||||
|
head->DATA=second;
|
||||||
|
}
|
||||||
|
else pred=second;
|
||||||
|
|
||||||
|
/*refresh*/
|
||||||
|
resetbddassoc(system, assoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*next one*/
|
||||||
|
save=first;
|
||||||
|
first=first->NEXT;
|
||||||
|
/*first is contained in a list*/
|
||||||
|
save->NEXT=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroybddassoc( system );
|
||||||
|
destroybddsystem( system );
|
||||||
|
destroybddcircuit( circuit );
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*return all possible order of port */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern chain_list* permutations(befig_list* befig)
|
||||||
|
{
|
||||||
|
chain_list* port=NULL;
|
||||||
|
chain_list* groupchain=NULL;
|
||||||
|
bepor_list* bepor;
|
||||||
|
|
||||||
|
/*build group of variables which can be permuted*/
|
||||||
|
if (befig->BEBUS) {
|
||||||
|
groupchain=permute_variable(NULL,befig->BEBUS->BIABL->CNDABL);
|
||||||
|
groupchain=permute_variable(groupchain,befig->BEBUS->BIABL->VALABL);
|
||||||
|
}
|
||||||
|
else if (befig->BEREG) {
|
||||||
|
groupchain=permute_variable(NULL,befig->BEREG->BIABL->CNDABL);
|
||||||
|
groupchain=permute_variable(groupchain,befig->BEREG->BIABL->VALABL);
|
||||||
|
}
|
||||||
|
else if (befig->BEOUT) {
|
||||||
|
groupchain=permute_variable(NULL,befig->BEOUT->ABL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*build a base of order*/
|
||||||
|
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
|
||||||
|
port=addchain(port,bepor->NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
port=reverse(port);
|
||||||
|
|
||||||
|
/*build different list of permutations*/
|
||||||
|
return compose(port, groupchain);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - tree permutations
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LIB_PERMUTE_H
|
||||||
|
#define LIB_PERMUTE_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*return all possible order of port */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern chain_list* permutations __P ((befig_list* befig));
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - read all cells
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <mut.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include <mlu.h>
|
||||||
|
#include <abv.h>
|
||||||
|
#include "lon_normalize_register.h"
|
||||||
|
#include "lon_normalize_DAG.h"
|
||||||
|
#include "lon_normalize_simplify.h"
|
||||||
|
#include "lon_normalize_power.h"
|
||||||
|
#include "lon_lib_utils.h"
|
||||||
|
#include "lon_lib_negativ.h"
|
||||||
|
#include "lon_lib_format.h"
|
||||||
|
#include "lon_lib_permute.h"
|
||||||
|
#include "lon_lib_specifications.h"
|
||||||
|
#include "lon_lib_matching.h"
|
||||||
|
#include "lon_lib_reader.h"
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return a list of files in directory path with the extension ext */
|
||||||
|
/* if error in path then return NULL */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern chain_list *getfiles_with_ext (char *path, char *ext)
|
||||||
|
{
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *entry;
|
||||||
|
char *filename;
|
||||||
|
char *completefilename;
|
||||||
|
int filenamelength, extensionlength, pathlength;
|
||||||
|
chain_list *head;
|
||||||
|
|
||||||
|
if (!path || !ext) return NULL;
|
||||||
|
|
||||||
|
dir = opendir (path);
|
||||||
|
if (!dir) return NULL;
|
||||||
|
|
||||||
|
extensionlength = strlen (ext);
|
||||||
|
pathlength = strlen (path);
|
||||||
|
head=NULL;
|
||||||
|
|
||||||
|
while ((entry = readdir (dir)) != NULL) {
|
||||||
|
|
||||||
|
filename = entry->d_name;
|
||||||
|
filenamelength = strlen (filename);
|
||||||
|
|
||||||
|
if (filenamelength <= extensionlength) continue;
|
||||||
|
/* is extension of filename accepted */
|
||||||
|
if (strncmp (filename + filenamelength - extensionlength,
|
||||||
|
ext, extensionlength)) continue;
|
||||||
|
|
||||||
|
completefilename = mbkalloc(filenamelength + 1);
|
||||||
|
sprintf(completefilename, "%s", filename);
|
||||||
|
head = addchain (head, completefilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* build the cell library */
|
||||||
|
/*****************************************************************************/
|
||||||
|
extern void library_reader(char* cell_directory)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
chain_list* vbe_list, *chain;
|
||||||
|
befig_list* befig;
|
||||||
|
char* memo_work;
|
||||||
|
char** memo_cata;
|
||||||
|
char* new_cata[2];
|
||||||
|
|
||||||
|
if (!cell_directory) {
|
||||||
|
fprintf(stderr,"library_reader: no Cell directory\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*seek vbe files which describe the lib*/
|
||||||
|
vbe_list=getfiles_with_ext (cell_directory, ".vbe");
|
||||||
|
|
||||||
|
if (!vbe_list /*list of name*/) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Mapping Error: no cell in directory '%s'\n",
|
||||||
|
cell_directory?cell_directory:".");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*search only in our library not to interfer with others*/
|
||||||
|
memo_work=WORK_LIB;
|
||||||
|
memo_cata=CATA_LIB;
|
||||||
|
WORK_LIB=cell_directory;
|
||||||
|
CATA_LIB=new_cata;
|
||||||
|
new_cata[0]=cell_directory;
|
||||||
|
new_cata[1]=NULL;
|
||||||
|
|
||||||
|
for (chain=vbe_list; chain; chain=chain->NEXT) {
|
||||||
|
|
||||||
|
/*put off extension*/
|
||||||
|
name=chain->DATA;
|
||||||
|
name[strlen(name)-strlen(".vbe")]='\0';
|
||||||
|
|
||||||
|
/* mode: BVL_KEEPAUX , BVL_TRACE ... */
|
||||||
|
/*do not keep aux*/
|
||||||
|
befig=vhdlloadbefig(NULL,name,0/*don't dump message*/);
|
||||||
|
if (befig->ERRFLG) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"BEH: unknown error %d in %s.vbe\n",befig->ERRFLG,name);
|
||||||
|
fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*detect power and forbid Vdd and Vss in expression*/
|
||||||
|
if (!detect_power(befig)) {
|
||||||
|
fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",befig->NAME);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*simplify abl expression */
|
||||||
|
simplify_expr(befig);
|
||||||
|
|
||||||
|
/*remove stable -needed by DAG_control()- */
|
||||||
|
if (!format_register(befig)) {
|
||||||
|
fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",befig->NAME);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*control cycles in befig and erase unused bebux and beaux*/
|
||||||
|
if (!DAG_control(befig)) {
|
||||||
|
fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",befig->NAME);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if constraints are respected*/
|
||||||
|
if (!format_cell(befig)) {
|
||||||
|
fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",befig->NAME);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*put the locon of lofig in the same order than bepor of befig*/
|
||||||
|
if (sortbepor(befig)) {
|
||||||
|
fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",befig->NAME);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*memorize cell if not already exists*/
|
||||||
|
addCell(befig);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
freechain(vbe_list);
|
||||||
|
|
||||||
|
/*relax old env*/
|
||||||
|
WORK_LIB=memo_work;
|
||||||
|
CATA_LIB=memo_cata;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - read all cells
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LIB_READER_H
|
||||||
|
#define LIB_READER_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return a list of files in directory path with the extension ext */
|
||||||
|
/* if error in path then return NULL */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern chain_list *getfiles_with_ext __P ((char *path, char *ext));
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* build the cell library */
|
||||||
|
/*****************************************************************************/
|
||||||
|
extern void library_reader __P ((char* cell_directory));
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,540 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - cell properties
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include "lon_lib_specifications.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*caracteristics of cell*/
|
||||||
|
#ifndef AREA
|
||||||
|
#define AREA "area"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRANSISTORS
|
||||||
|
#define TRANSISTORS "transistors"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*for inputs*/
|
||||||
|
#ifndef Cin /* cin_i */
|
||||||
|
#define Cin "cin"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*for output*/
|
||||||
|
#ifndef Rup /* rup_i_t */
|
||||||
|
#define Rup "rup"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Rdown /* rdown_i_t */
|
||||||
|
#define Rdown "rdown"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*for inputs to output: Tphl_i_t */
|
||||||
|
#ifndef Tphl
|
||||||
|
#define Tphl "tphl"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Tpll
|
||||||
|
#define Tpll "tpll"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Tplh
|
||||||
|
#define Tplh "tplh"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Tphh
|
||||||
|
#define Tphh "tphh"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*for flip-flop*/
|
||||||
|
#ifndef Tsr /* tsr_i_ck */
|
||||||
|
#define Tsr "tsr"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Tsf /* tsf_i_ck */
|
||||||
|
#define Tsf "tsf"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Thr /* thr_i_ck */
|
||||||
|
#define Thr "thr"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Thf /* thf_i_ck*/
|
||||||
|
#define Thf "thf"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Tar /* tar_ck_q */
|
||||||
|
#define Tar "tar"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Taf /* taf_ck_q */
|
||||||
|
#define Taf "taf"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* to avoid manip of pointer */
|
||||||
|
/******************************************************************************/
|
||||||
|
static int getvalue(begen_list* begen)
|
||||||
|
{
|
||||||
|
int *pt_val;
|
||||||
|
pt_val=begen->VALUE;
|
||||||
|
return *pt_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* to avoid manip of pointer */
|
||||||
|
/******************************************************************************/
|
||||||
|
static void* putvalue(int value)
|
||||||
|
{
|
||||||
|
int *pt_val;
|
||||||
|
pt_val=mbkalloc(sizeof(int));
|
||||||
|
*pt_val=value;
|
||||||
|
return pt_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* return the value of a generic named name in befig */
|
||||||
|
/*****************************************************************************/
|
||||||
|
static int getgeneric(befig_list* befig, char* name)
|
||||||
|
{
|
||||||
|
begen_list* begen;
|
||||||
|
|
||||||
|
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
|
||||||
|
if (begen->NAME==name) return getvalue(begen);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr,"Mapping Error: generic '%s' not found in cell %s\n",
|
||||||
|
name,befig->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the area cell in lambda² size */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int getgenericarea(befig_list* befig)
|
||||||
|
{
|
||||||
|
return getgeneric(befig,namealloc(AREA));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* set the area cell in lamda² size */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void putgenericarea(befig_list* befig, int value)
|
||||||
|
{
|
||||||
|
befig->BEGEN=beh_addbegen(befig->BEGEN, namealloc(AREA),
|
||||||
|
namealloc("natural"), putvalue(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the setup Time of an entry in pico second */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern double getgenericT(befig_list* befig, char* name)
|
||||||
|
{
|
||||||
|
begen_list* begen;
|
||||||
|
char* Thl, *Tll, *Tlh, *Thh, *tar, *taf;
|
||||||
|
int T_setup=0;
|
||||||
|
int count=0;
|
||||||
|
char memo;
|
||||||
|
char *output;
|
||||||
|
|
||||||
|
if (befig->BEOUT) output=befig->BEOUT->NAME;
|
||||||
|
else if (befig->BEBUS) output=befig->BEBUS->NAME;
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"BEH: output is missing in %s\n",befig->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memo=SEPAR;
|
||||||
|
SEPAR='_';
|
||||||
|
Thl=concatname(Tphl,name);
|
||||||
|
Tll=concatname(Tpll,name);
|
||||||
|
Thh=concatname(Tphh,name);
|
||||||
|
Tlh=concatname(Tplh,name);
|
||||||
|
tar=concatname(Tar,name);
|
||||||
|
taf=concatname(Taf,name);
|
||||||
|
Thl=concatname(Thl,output);
|
||||||
|
Tll=concatname(Tll,output);
|
||||||
|
Thh=concatname(Thh,output);
|
||||||
|
Tlh=concatname(Tlh,output);
|
||||||
|
tar=concatname(tar,output);
|
||||||
|
taf=concatname(taf,output);
|
||||||
|
SEPAR=memo;
|
||||||
|
|
||||||
|
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
|
||||||
|
if (begen->NAME==Thl || begen->NAME==Thh || begen->NAME==Tlh
|
||||||
|
|| begen->NAME==Tll || begen->NAME==tar || begen->NAME==taf) {
|
||||||
|
T_setup+=getvalue(begen);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count==0) return 0;
|
||||||
|
return (double) T_setup/count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the setup in high value of an entry in pico second */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern double getgenericTh(befig_list* befig, char* name)
|
||||||
|
{
|
||||||
|
begen_list* begen;
|
||||||
|
char *Tlh, *Thh;
|
||||||
|
int T_setup=0;
|
||||||
|
int count=0;
|
||||||
|
char memo;
|
||||||
|
char *output;
|
||||||
|
|
||||||
|
if (befig->BEOUT) output=befig->BEOUT->NAME;
|
||||||
|
else if (befig->BEBUS) output=befig->BEBUS->NAME;
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"BEH: output is missing in %s\n",befig->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memo=SEPAR;
|
||||||
|
SEPAR='_';
|
||||||
|
Thh=concatname(Tphh,name);
|
||||||
|
Tlh=concatname(Tplh,name);
|
||||||
|
Thh=concatname(Thh,output);
|
||||||
|
Tlh=concatname(Tlh,output);
|
||||||
|
SEPAR=memo;
|
||||||
|
|
||||||
|
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
|
||||||
|
if (begen->NAME==Thh || begen->NAME==Tlh) {
|
||||||
|
T_setup+=getvalue(begen);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count==0) return 0;
|
||||||
|
return (double) T_setup/count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the setup in low value of an entry in pico second */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern double getgenericTl(befig_list* befig, char* name)
|
||||||
|
{
|
||||||
|
begen_list* begen;
|
||||||
|
char* Thl, *Tll;
|
||||||
|
int T_setup=0;
|
||||||
|
int count=0;
|
||||||
|
char memo;
|
||||||
|
char *output;
|
||||||
|
|
||||||
|
if (befig->BEOUT) output=befig->BEOUT->NAME;
|
||||||
|
else if (befig->BEBUS) output=befig->BEBUS->NAME;
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"BEH: output is missing in %s\n",befig->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memo=SEPAR;
|
||||||
|
SEPAR='_';
|
||||||
|
Thl=concatname(Tphl,name);
|
||||||
|
Tll=concatname(Tpll,name);
|
||||||
|
Thl=concatname(Thl,output);
|
||||||
|
Tll=concatname(Tll,output);
|
||||||
|
SEPAR=memo;
|
||||||
|
|
||||||
|
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
|
||||||
|
if (begen->NAME==Thl || begen->NAME==Tll) {
|
||||||
|
T_setup+=getvalue(begen);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count==0) return 0;
|
||||||
|
return (double) T_setup/count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* set the setup Times of an entry in pico second (exp-12) */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void putgenericT(befig_list* befig, char* name, double Thl_value, double Tll_value, double Tlh_value, double Thh_value)
|
||||||
|
{
|
||||||
|
char* Thl, *Tll, *Tlh, *Thh;
|
||||||
|
char memo;
|
||||||
|
char *output;
|
||||||
|
|
||||||
|
if (befig->BEOUT) output=befig->BEOUT->NAME;
|
||||||
|
else if (befig->BEBUS) output=befig->BEBUS->NAME;
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"BEH: output is missing in %s\n",befig->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memo=SEPAR;
|
||||||
|
SEPAR='_';
|
||||||
|
Thl=concatname(Tphl,name);
|
||||||
|
Tll=concatname(Tpll,name);
|
||||||
|
Thh=concatname(Tphh,name);
|
||||||
|
Tlh=concatname(Tplh,name);
|
||||||
|
Thl=concatname(Thl,output);
|
||||||
|
Tll=concatname(Tll,output);
|
||||||
|
Thh=concatname(Thh,output);
|
||||||
|
Tlh=concatname(Tlh,output);
|
||||||
|
SEPAR=memo;
|
||||||
|
|
||||||
|
befig->BEGEN=beh_addbegen(befig->BEGEN,Thl,namealloc("natural"),
|
||||||
|
putvalue((int)Thl_value));
|
||||||
|
befig->BEGEN=beh_addbegen(befig->BEGEN,Tll,namealloc("natural"),
|
||||||
|
putvalue((int)Tll_value));
|
||||||
|
befig->BEGEN=beh_addbegen(befig->BEGEN,Tlh,namealloc("natural"),
|
||||||
|
putvalue((int)Tlh_value));
|
||||||
|
befig->BEGEN=beh_addbegen(befig->BEGEN,Thh,namealloc("natural"),
|
||||||
|
putvalue((int)Thh_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the Capacitance of an entry in pico Farad (exp-12) */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern double getgenericC(befig_list* befig, char* name)
|
||||||
|
{
|
||||||
|
begen_list* begen;
|
||||||
|
char* C_name;
|
||||||
|
char memo;
|
||||||
|
|
||||||
|
memo=SEPAR;
|
||||||
|
SEPAR='_';
|
||||||
|
C_name=concatname(Cin,name); /*namealloc() hidden*/
|
||||||
|
SEPAR=memo;
|
||||||
|
|
||||||
|
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
|
||||||
|
/* femto Farad (exp-15) -> pico Farad (exp-12) */
|
||||||
|
if (begen->NAME==C_name) return (double)getvalue(begen)/1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* set the Capacitance of an entry in pico Farad */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void putgenericC(befig_list* befig, char* name, double C_value)
|
||||||
|
{
|
||||||
|
char* C_name;
|
||||||
|
char memo;
|
||||||
|
|
||||||
|
memo=SEPAR;
|
||||||
|
SEPAR='_';
|
||||||
|
C_name=concatname(Cin,name); /*namealloc() hidden*/
|
||||||
|
SEPAR=memo;
|
||||||
|
|
||||||
|
/* pico Farad (exp-12) -> femto Farad (exp-15) */
|
||||||
|
befig->BEGEN=beh_addbegen(befig->BEGEN,C_name,namealloc("natural"),
|
||||||
|
putvalue((int)(C_value*1000)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*return the average of Resistivity in Ohm of path from input to output cell */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int getgenericR(befig_list* befig, char* name)
|
||||||
|
{
|
||||||
|
begen_list* begen;
|
||||||
|
char* R_up, *R_down;
|
||||||
|
int R=0;
|
||||||
|
int count=0;
|
||||||
|
char memo;
|
||||||
|
char *output;
|
||||||
|
|
||||||
|
if (befig->BEOUT) output=befig->BEOUT->NAME;
|
||||||
|
else if (befig->BEBUS) output=befig->BEBUS->NAME;
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"BEH: output is missing in %s\n",befig->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memo=SEPAR;
|
||||||
|
SEPAR='_';
|
||||||
|
R_up=concatname(Rup,name);
|
||||||
|
R_down=concatname(Rdown,name);
|
||||||
|
R_up=concatname(R_up,output);
|
||||||
|
R_down=concatname(R_down,output);
|
||||||
|
SEPAR=memo;
|
||||||
|
|
||||||
|
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
|
||||||
|
if (begen->NAME==R_up || begen->NAME==R_down) {
|
||||||
|
R+=getvalue(begen);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count==0) return 0;
|
||||||
|
return (double) R/count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* set Resistivity in Ohm of path from input to output cell */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void putgenericR(befig_list* befig, char* name, double Rup_value, double Rdown_value)
|
||||||
|
{
|
||||||
|
char* R_up, *R_down;
|
||||||
|
char memo;
|
||||||
|
char *output;
|
||||||
|
|
||||||
|
if (befig->BEOUT) output=befig->BEOUT->NAME;
|
||||||
|
else if (befig->BEBUS) output=befig->BEBUS->NAME;
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"BEH: output is missing in %s\n",befig->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memo=SEPAR;
|
||||||
|
SEPAR='_';
|
||||||
|
R_up=concatname(Rup,name);
|
||||||
|
R_down=concatname(Rdown,name);
|
||||||
|
R_up=concatname(R_up,output);
|
||||||
|
R_down=concatname(R_down,output);
|
||||||
|
SEPAR=memo;
|
||||||
|
|
||||||
|
befig->BEGEN=beh_addbegen(befig->BEGEN,R_up,namealloc("natural"),
|
||||||
|
putvalue((int)Rup_value));
|
||||||
|
befig->BEGEN=beh_addbegen(befig->BEGEN,R_down,namealloc("natural"),
|
||||||
|
putvalue((int)Rdown_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*return the Rup in Ohm of path from input to output cell */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int getgenericRup(befig_list* befig, char* name)
|
||||||
|
{
|
||||||
|
begen_list* begen;
|
||||||
|
char* R_up;
|
||||||
|
int R=0;
|
||||||
|
int count=0;
|
||||||
|
char memo;
|
||||||
|
char *output;
|
||||||
|
|
||||||
|
if (befig->BEOUT) output=befig->BEOUT->NAME;
|
||||||
|
else if (befig->BEBUS) output=befig->BEBUS->NAME;
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"BEH: output is missing in %s\n",befig->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memo=SEPAR;
|
||||||
|
SEPAR='_';
|
||||||
|
R_up=concatname(Rup,name);
|
||||||
|
R_up=concatname(R_up,output);
|
||||||
|
SEPAR=memo;
|
||||||
|
|
||||||
|
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
|
||||||
|
if (begen->NAME==R_up) {
|
||||||
|
R+=getvalue(begen);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count==0) return 0;
|
||||||
|
return (double) R/count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*return the Rdown in Ohm of path from input to output cell */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int getgenericRdown(befig_list* befig, char* name)
|
||||||
|
{
|
||||||
|
begen_list* begen;
|
||||||
|
char* R_down;
|
||||||
|
int R=0;
|
||||||
|
int count=0;
|
||||||
|
char memo;
|
||||||
|
char *output;
|
||||||
|
|
||||||
|
if (befig->BEOUT) output=befig->BEOUT->NAME;
|
||||||
|
else if (befig->BEBUS) output=befig->BEBUS->NAME;
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"BEH: output is missing in %s\n",befig->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memo=SEPAR;
|
||||||
|
SEPAR='_';
|
||||||
|
R_down=concatname(Rdown,name);
|
||||||
|
R_down=concatname(R_down,output);
|
||||||
|
SEPAR=memo;
|
||||||
|
|
||||||
|
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
|
||||||
|
if (begen->NAME==R_down) {
|
||||||
|
R+=getvalue(begen);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count==0) return 0;
|
||||||
|
return (double) R/count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the average of Capacitance of all inputs in pico Farad */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int getaverageC(befig_list* befig)
|
||||||
|
{
|
||||||
|
bepor_list* bepor;
|
||||||
|
int C=0;
|
||||||
|
int count=0;
|
||||||
|
|
||||||
|
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
|
||||||
|
/*only input*/
|
||||||
|
if (bepor->DIRECTION!=IN && bepor->DIRECTION!=INOUT
|
||||||
|
&& bepor->DIRECTION!=TRANSCV) continue;
|
||||||
|
if (isvdd(bepor->NAME) || isvss(bepor->NAME)) continue;
|
||||||
|
count++;
|
||||||
|
C+=getgenericC(befig,bepor->NAME); /* in fF */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count==0) return 0;
|
||||||
|
return (double)C/count/1000; /* femto Farad (exp-15) -> pico Farad (exp-12)*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - cell properties
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LIB_SPECIFICATIONS_H
|
||||||
|
#define LIB_SPECIFICATIONS_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the area cell in lambda² size */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int getgenericarea __P ((befig_list* befig));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* set the area cell in lamda² size */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void putgenericarea __P ((befig_list* befig, int value));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the setup Time of an entry in pico second (exp-12) */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern double getgenericT __P ((befig_list* befig, char* name));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the setup in high value of an entry in pico second */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern double getgenericTh __P ((befig_list* befig, char* name));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the setup in low value of an entry in pico second */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern double getgenericTl __P ((befig_list* befig, char* name));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* set the setup Times of an entry in pico second (exp-12) */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void putgenericT __P ((befig_list* befig, char* name, double Thl_value, double Tll_value, double Tlh_value, double Thh_value));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the Capacitance of an entry in pico Farad (exp-12) */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern double getgenericC __P ((befig_list* befig, char* name));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* set the Capacitance of an entry in pico Farad */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void putgenericC __P ((befig_list* befig, char* name, double C_value));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*return the average of Resistivity in Ohm of path from input to output cell */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int getgenericR __P ((befig_list* befig, char* name));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*return the Rup in Ohm of path from input to output cell */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int getgenericRup __P ((befig_list* befig, char* name));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*return the Rdown in Ohm of path from input to output cell */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int getgenericRdown __P ((befig_list* befig, char* name));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* set Resistivity in Ohm of path from input to output cell */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void putgenericR __P ((befig_list* befig, char* name, double Rup_value, double Rdown_value));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the average of Capacitance of all inputs in pico Farad */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int getaverageC __P ((befig_list* befig));
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,438 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - library cells utilities
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include "lon_lax_param.h"
|
||||||
|
#include "lon_signal_name.h"
|
||||||
|
#include "lon_lib_matching.h"
|
||||||
|
#include "lon_lib_specifications.h"
|
||||||
|
#include "lon_lib_permute.h"
|
||||||
|
#include "lon_lib_utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*size of memory block*/
|
||||||
|
#define BLOCK 512
|
||||||
|
|
||||||
|
|
||||||
|
/*heap*/
|
||||||
|
static port_list* PORT;
|
||||||
|
/*list of cells with different behaviour*/
|
||||||
|
static chain_list* CELLS;
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* take from the heap */
|
||||||
|
/***************************************************************************/
|
||||||
|
static port_list* newport()
|
||||||
|
{
|
||||||
|
port_list* new;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!PORT) {
|
||||||
|
PORT=mbkalloc(BLOCK*sizeof(port_list));
|
||||||
|
new=PORT;
|
||||||
|
for (i = 1; i < BLOCK; i++) {
|
||||||
|
new->NEXT = new + 1;
|
||||||
|
new++;
|
||||||
|
}
|
||||||
|
new->NEXT = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
new=PORT;
|
||||||
|
PORT=PORT->NEXT;
|
||||||
|
|
||||||
|
/*fill signal*/
|
||||||
|
new->NEXT=NULL; /*not to interfer with below*/
|
||||||
|
new->C=0;
|
||||||
|
new->R=0;
|
||||||
|
new->T=0;
|
||||||
|
new->NAME=NULL;
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* free a list of port */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void delport(port_list* head)
|
||||||
|
{
|
||||||
|
if (!head) return;
|
||||||
|
delport(head->NEXT);
|
||||||
|
head->NEXT=PORT;
|
||||||
|
PORT=head;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*duplicate a list of port but not its contents */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern port_list* copyport(port_list* head)
|
||||||
|
{
|
||||||
|
port_list *new;
|
||||||
|
|
||||||
|
if (!head) return NULL;
|
||||||
|
new=newport();
|
||||||
|
new->NEXT=copyport(head->NEXT);
|
||||||
|
new->C=head->C;
|
||||||
|
new->R=head->R;
|
||||||
|
new->T=head->T;
|
||||||
|
new->NAME=head->NAME;
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* copy values of head to new recursively */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void moveport(port_list* head, port_list* new)
|
||||||
|
{
|
||||||
|
if (!head && !new) return;
|
||||||
|
if (!head || !new) {
|
||||||
|
fprintf(stderr,"moveport: discrepancy in length\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
moveport(head->NEXT,new->NEXT);
|
||||||
|
new->C=head->C;
|
||||||
|
new->R=head->R;
|
||||||
|
new->T=head->T;
|
||||||
|
new->NAME=head->NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*build a new cell in our library */
|
||||||
|
/* port of cell is the inverted list of bepor */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern cell_list* copyCell(cell_list* old)
|
||||||
|
{
|
||||||
|
cell_list* cell;
|
||||||
|
|
||||||
|
cell=(cell_list*) mbkalloc(sizeof(cell_list));
|
||||||
|
|
||||||
|
cell->BEFIG=old->BEFIG;
|
||||||
|
cell->NAME=old->NAME;
|
||||||
|
cell->AREA=old->AREA;
|
||||||
|
cell->MODE=old->MODE;
|
||||||
|
cell->PORT=old->PORT;
|
||||||
|
cell->NEXT=old->NEXT;
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* build a lofig with namechain for interface and with lofig for instance */
|
||||||
|
/*directly connected to external port */
|
||||||
|
/******************************************************************************/
|
||||||
|
static lofig_list* build_lofig(lofig_list* lofig, chain_list* nameorder)
|
||||||
|
{
|
||||||
|
long index=0;
|
||||||
|
locon_list* locon;
|
||||||
|
char memo;
|
||||||
|
lofig_list* new;
|
||||||
|
char* name;
|
||||||
|
chain_list* sigchain=NULL, *namechain;
|
||||||
|
losig_list* losig;
|
||||||
|
|
||||||
|
memo=SEPAR;
|
||||||
|
SEPAR='_';
|
||||||
|
new=addlofig(getautoname(lofig->NAME));
|
||||||
|
SEPAR=memo;
|
||||||
|
|
||||||
|
for ( ; nameorder; nameorder=nameorder->NEXT) {
|
||||||
|
name=(char*) nameorder->DATA;
|
||||||
|
/*search locon*/
|
||||||
|
for (locon=lofig->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
|
||||||
|
locon->NAME,lofig->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (locon->NAME==name) break;
|
||||||
|
}
|
||||||
|
if (!locon) {
|
||||||
|
fprintf(stderr,"build_lofig: no locon '%s' found in '%s'\n",name,
|
||||||
|
lofig->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
namechain=addchain(NULL,name);
|
||||||
|
losig=addlosig(new, index++, namechain, EXTERNAL);
|
||||||
|
addlocon(new, locon->NAME, losig, locon->DIRECTION);
|
||||||
|
sigchain=addchain(sigchain,losig);
|
||||||
|
}
|
||||||
|
|
||||||
|
sigchain=reverse(sigchain);
|
||||||
|
addloins(new, lofig->NAME, lofig, sigchain);
|
||||||
|
freechain(sigchain);
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*build a new cell in our library */
|
||||||
|
/*take properties in order */
|
||||||
|
/******************************************************************************/
|
||||||
|
static cell_list* properties_addCell(befig_list* befig, lofig_list *lofig)
|
||||||
|
{
|
||||||
|
cell_list* cell;
|
||||||
|
port_list* new;
|
||||||
|
bepor_list* bepor;
|
||||||
|
locon_list* locon;
|
||||||
|
losig_list* losig;
|
||||||
|
|
||||||
|
|
||||||
|
cell=(cell_list*) mbkalloc(sizeof(cell_list));
|
||||||
|
|
||||||
|
cell->NAME=lofig->NAME;
|
||||||
|
cell->AREA=getgenericarea(befig);
|
||||||
|
cell->MODE='A'; /*to flatten later*/
|
||||||
|
cell->NEXT=NULL;
|
||||||
|
cell->BEFIG=befig;
|
||||||
|
cell->PORT=NULL;
|
||||||
|
|
||||||
|
/*buils port*/
|
||||||
|
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
|
||||||
|
new=newport();
|
||||||
|
new->NEXT=cell->PORT;
|
||||||
|
cell->PORT=new;
|
||||||
|
new->NAME=bepor->NAME;
|
||||||
|
/*only for real input*/
|
||||||
|
if (bepor->DIRECTION==OUT || bepor->DIRECTION==TRISTATE
|
||||||
|
|| isvdd(bepor->NAME) || isvss(bepor->NAME)) continue;
|
||||||
|
|
||||||
|
/*search locon in model*/
|
||||||
|
for (locon=lofig->LOCON; locon; locon=locon->NEXT){
|
||||||
|
if (bepor->NAME==locon->NAME) break;
|
||||||
|
}
|
||||||
|
if (!locon) {
|
||||||
|
fprintf(stderr,"properties_addCell: locon '%s' not found\n",
|
||||||
|
locon->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
losig=locon->SIG;
|
||||||
|
|
||||||
|
/*search real connection*/
|
||||||
|
for (locon=lofig->LOINS->LOCON; locon; locon=locon->NEXT){
|
||||||
|
if (losig==locon->SIG) break;
|
||||||
|
}
|
||||||
|
if (!locon) {
|
||||||
|
fprintf(stderr,"properties_addCell: locon '%s' not found in cell\n",
|
||||||
|
locon->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*apply properties*/
|
||||||
|
new->R=getgenericR(befig, locon->NAME);
|
||||||
|
new->C=getgenericC(befig, locon->NAME);
|
||||||
|
new->T=getgenericT(befig, locon->NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*put in the same order than bepor*/
|
||||||
|
cell->PORT=(port_list*) reverse((chain_list*) cell->PORT);
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*insert cell in library and also its permutations */
|
||||||
|
/******************************************************************************/
|
||||||
|
static cell_list* insertCell(befig_list* befig, cell_list* top_lib)
|
||||||
|
{
|
||||||
|
lofig_list* lofig, *new;
|
||||||
|
cell_list* cell;
|
||||||
|
chain_list* orderchain, *order, *chain;
|
||||||
|
|
||||||
|
/*insert first cell with right order of port*/
|
||||||
|
cell=createCell(befig);
|
||||||
|
/*insert new cell in our library*/
|
||||||
|
cell->NEXT= top_lib;
|
||||||
|
top_lib=cell;
|
||||||
|
|
||||||
|
/*build other cells with port permutations */
|
||||||
|
lofig=getlofig(befig->NAME,'P');
|
||||||
|
orderchain=permutations(befig);
|
||||||
|
|
||||||
|
for (chain=orderchain; chain; chain=chain->NEXT) {
|
||||||
|
/*build a new cell with order*/
|
||||||
|
order=chain->DATA;
|
||||||
|
new=build_lofig(lofig,order);
|
||||||
|
cell=properties_addCell(befig,new);
|
||||||
|
/*insert new cell in our library*/
|
||||||
|
cell->NEXT= top_lib;
|
||||||
|
top_lib=cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (chain=orderchain; chain; chain=chain->NEXT) {
|
||||||
|
freechain(chain->DATA);
|
||||||
|
}
|
||||||
|
freechain(orderchain);
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*build a new cell in our library */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern cell_list* createCell(befig_list* befig)
|
||||||
|
{
|
||||||
|
cell_list* cell;
|
||||||
|
port_list* new;
|
||||||
|
bepor_list* bepor;
|
||||||
|
|
||||||
|
|
||||||
|
cell=(cell_list*) mbkalloc(sizeof(cell_list));
|
||||||
|
|
||||||
|
cell->NAME=befig->NAME;
|
||||||
|
cell->AREA=getgenericarea(befig);
|
||||||
|
cell->MODE='P';
|
||||||
|
cell->NEXT=NULL;
|
||||||
|
cell->BEFIG=befig;
|
||||||
|
|
||||||
|
cell->PORT=NULL;
|
||||||
|
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
|
||||||
|
new=newport();
|
||||||
|
new->NEXT=cell->PORT;
|
||||||
|
cell->PORT=new;
|
||||||
|
new->NAME=bepor->NAME;
|
||||||
|
/*only for real input*/
|
||||||
|
if ((bepor->DIRECTION==IN || bepor->DIRECTION==INOUT
|
||||||
|
|| bepor->DIRECTION==TRANSCV) && !isvdd(new->NAME) && !isvss(new->NAME)) {
|
||||||
|
new->R=getgenericR(befig,bepor->NAME);
|
||||||
|
new->C=getgenericC(befig,bepor->NAME);
|
||||||
|
new->T=getgenericT(befig,bepor->NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*put in the same order than bepor*/
|
||||||
|
cell->PORT=(port_list*) reverse((chain_list*) cell->PORT);
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*add and classify a cell to our library */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void addCell(befig_list* befig)
|
||||||
|
{
|
||||||
|
chain_list *chain;
|
||||||
|
cell_list* cell;
|
||||||
|
|
||||||
|
/*search same behaviour*/
|
||||||
|
for (chain=CELLS; chain; chain=chain->NEXT) {
|
||||||
|
cell= (cell_list*) chain->DATA;
|
||||||
|
if (compare_befig(cell->BEFIG,befig)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*insert cell*/
|
||||||
|
if (!chain) {
|
||||||
|
CELLS=addchain(CELLS,NULL);
|
||||||
|
chain=CELLS;
|
||||||
|
}
|
||||||
|
/*insert at the top of chain*/
|
||||||
|
chain->DATA=insertCell(befig, (cell_list*) chain->DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the cell named */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern cell_list* getCell(char *name)
|
||||||
|
{
|
||||||
|
chain_list* chain;
|
||||||
|
cell_list* cell;
|
||||||
|
|
||||||
|
for (chain=CELLS; chain; chain=chain->NEXT) {
|
||||||
|
for (cell=(cell_list*) chain->DATA; cell; cell=cell->NEXT) {
|
||||||
|
if (cell->NAME==name) return cell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return a buffer of our library */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern cell_list* getCellbuffer()
|
||||||
|
{
|
||||||
|
chain_list* chain;
|
||||||
|
cell_list* cell, *best;
|
||||||
|
befig_list* befig;
|
||||||
|
|
||||||
|
for (chain=CELLS; chain; chain=chain->NEXT) {
|
||||||
|
cell=(cell_list*) chain->DATA;
|
||||||
|
befig=cell->BEFIG;
|
||||||
|
if (befig->BEREG || befig->BEBUS || !befig->BEOUT) continue;
|
||||||
|
/*simple affect*/
|
||||||
|
if (ABL_ATOM(befig->BEOUT->ABL)) {
|
||||||
|
best=cell;
|
||||||
|
for (cell=cell->NEXT; cell; cell=cell->NEXT) {
|
||||||
|
if (best->AREA>cell->AREA) cell=best;
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the list of cells with the same behaviour than named */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern cell_list* sameCells(char *name)
|
||||||
|
{
|
||||||
|
chain_list* chain;
|
||||||
|
cell_list* cell;
|
||||||
|
|
||||||
|
for (chain=CELLS; chain; chain=chain->NEXT) {
|
||||||
|
for (cell=(cell_list*) chain->DATA; cell; cell=cell->NEXT) {
|
||||||
|
if (cell->NAME==name) return (cell_list*) chain->DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - library cells utilities
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LIB_UTILS_H
|
||||||
|
#define LIB_UTILS_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*image of a port of a befig*/
|
||||||
|
typedef struct port {
|
||||||
|
struct port* NEXT;
|
||||||
|
char *NAME; /*name of bepor*/
|
||||||
|
double T; /* (Tphh+Tpll+Tplh+Tphl)/4 in ps */
|
||||||
|
double C; /* Cin in pF */
|
||||||
|
double R; /* Rout in Ohm */
|
||||||
|
} port_list;
|
||||||
|
|
||||||
|
/*image of a befig from the cell library*/
|
||||||
|
typedef struct cell {
|
||||||
|
struct cell* NEXT;
|
||||||
|
port_list* PORT; /*image of bepor*/
|
||||||
|
char* NAME; /*name of befig*/
|
||||||
|
int AREA;
|
||||||
|
char MODE; /*'P' for partial ; 'A' for all */
|
||||||
|
befig_list* BEFIG; /*befig represented*/
|
||||||
|
} cell_list;
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*build a new cell in our library */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern cell_list* createCell __P ((befig_list* befig));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*build a new cell in our library */
|
||||||
|
/* port of cell is the inverted list of bepor */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void addCell __P ((befig_list* befig));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*build a new cell in our library */
|
||||||
|
/* port of cell is the inverted list of bepor */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern cell_list* copyCell __P ((cell_list* old));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*duplicate a list of port but not its contents */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern port_list* copyport __P ((port_list* head));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* copy values of head to new recursively */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void moveport __P ((port_list* head, port_list* new_head));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* free a list of port */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void delport __P ((port_list* head));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the cell named */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern cell_list* getCell __P ((char *name));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return a buffer of our library */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern cell_list* getCellbuffer __P (());
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the list of cells with the same behaviour than named */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern cell_list* sameCells __P ((char *name));
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,498 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - Light optimizing on Nets
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <mut.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <mlu.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include <abv.h>
|
||||||
|
#include <aut.h>
|
||||||
|
#include <bdd.h>
|
||||||
|
#include "lon_lax_param.h"
|
||||||
|
#include "lon_signal_utils.h"
|
||||||
|
#include "lon_signal_netlist.h"
|
||||||
|
#include "lon_signal_critical.h"
|
||||||
|
#include "lon_optim_capa.h"
|
||||||
|
#include "lon_lib_utils.h"
|
||||||
|
#include "lon_lax_param.h"
|
||||||
|
#include "lon_xsch_driver.h"
|
||||||
|
#include "lon_lib_reader.h"
|
||||||
|
#include "lon_optim_stats.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LOON
|
||||||
|
#define LOON "loon"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define USAGE \
|
||||||
|
"usage: "LOON" <input_file> <output_file> [<lax_file>]\n"
|
||||||
|
|
||||||
|
|
||||||
|
/*usage with options*/
|
||||||
|
#define OPT_USAGE USAGE \
|
||||||
|
" "LOON" -h\n"\
|
||||||
|
" "LOON" -o <input_file>\n"\
|
||||||
|
" "LOON" <input_file> <output_file> [-l <lax_file>] [-x <xsch_mode>] [-m <optim_mode>]\n"
|
||||||
|
|
||||||
|
|
||||||
|
#define HELP_USAGE OPT_USAGE "\n"\
|
||||||
|
"\t-h Displays this help page.\n"\
|
||||||
|
"\t-o <input_file> Overwrites <input_file> with new netlist.\n"\
|
||||||
|
"\t-m <optim_mode> Optimization mode number. Area(0) to delay(4).\n"\
|
||||||
|
"\t-x <xsch_mode> XSC color mode. Critical path(0) or delay gradient(1).\n"\
|
||||||
|
"\t <input_file> VST input file name.\n"\
|
||||||
|
"\t <output_file> VST output file name.\n"\
|
||||||
|
"\t-l <lax_file> LAX parameter file name. See lax(1) for more info.\n"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*options*/
|
||||||
|
#define LAX_FILE 'l'
|
||||||
|
#define HELP_MODE 'h'
|
||||||
|
#define OPTIM_MODE 'm'
|
||||||
|
#define XSCH_MODE 'x'
|
||||||
|
#define OVERWRITE_MODE 'o'
|
||||||
|
|
||||||
|
/*options variables*/
|
||||||
|
extern char *optarg;
|
||||||
|
static int verbose_mode=0, optim_mode=DEFAULT_OPTIM, xsch_mode=XSCH_CRITICAL_PATH, overwrite_mode=0;
|
||||||
|
static char *input_file=NULL, *output_file=NULL, *lax_file=NULL, *xsch_file=NULL;
|
||||||
|
static char *mbk_target_lib=NULL, *mbk_in_lo=NULL, *mbk_out_lo=NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* set variables to values of command line */
|
||||||
|
/******************************************************************************/
|
||||||
|
static void set_param(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#if 0 /*incompatibilite entre Linux et Solaris */
|
||||||
|
char opt;
|
||||||
|
|
||||||
|
/*options*/
|
||||||
|
while ((opt=getopt (argc, argv,"-l:m:x:ho")) != EOF) {
|
||||||
|
switch (opt) {
|
||||||
|
case OVERWRITE_MODE: overwrite_mode=1; break;
|
||||||
|
case OPTIM_MODE:
|
||||||
|
if (strlen(optarg)==1 && isdigit((int) optarg[0])) {
|
||||||
|
optim_mode=optarg[0]-'0';
|
||||||
|
if (optim_mode<=OPTIM_DELAY4) break;
|
||||||
|
}
|
||||||
|
fprintf(stderr,OPT_USAGE "\n");
|
||||||
|
exit(1);
|
||||||
|
case XSCH_MODE:
|
||||||
|
if (strlen(optarg)==1 && isdigit((int) optarg[0])) {
|
||||||
|
xsch_mode=optarg[0]-'0';
|
||||||
|
if (xsch_mode<=XSCH_GRADIENT) break;
|
||||||
|
}
|
||||||
|
fprintf(stderr,OPT_USAGE "\n");
|
||||||
|
exit(1);
|
||||||
|
case LAX_FILE:
|
||||||
|
if (!lax_file) {lax_file=optarg; break;}
|
||||||
|
fprintf(stderr,OPT_USAGE "\n");
|
||||||
|
exit(1);
|
||||||
|
case 1 : /*all the other parameters without options (Linux only)*/
|
||||||
|
if (!input_file || input_file==argv[i]) {input_file=optarg; break;}
|
||||||
|
if (!output_file || output_file==argv[i]) {output_file=optarg; break;}
|
||||||
|
if (!lax_file || lax_file==argv[i]) {lax_file=optarg; break;}
|
||||||
|
fprintf(stderr,OPT_USAGE "\n");
|
||||||
|
exit(1);
|
||||||
|
case HELP_MODE:
|
||||||
|
fprintf(stdout,HELP_USAGE "\n");
|
||||||
|
exit(0);
|
||||||
|
case '?': default:
|
||||||
|
fprintf(stderr,OPT_USAGE "\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*verify for Sun and Solaris. getopt() isn't the same than Linux_elf */
|
||||||
|
for (i=1; i<argc; i++) {
|
||||||
|
if (!strcmp(argv[i],"-o")) {overwrite_mode=1; continue;}
|
||||||
|
if (!strcmp(argv[i],"-h")) {fprintf(stdout,HELP_USAGE "\n"); exit(0);}
|
||||||
|
/*take option and argument*/
|
||||||
|
if (!strcmp(argv[i],"-l")) {
|
||||||
|
if (++i<argc) {lax_file=argv[i]; continue;}
|
||||||
|
fprintf(stderr,OPT_USAGE "\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!strcmp(argv[i],"-x")) {
|
||||||
|
if (++i<argc && strlen(argv[i])==1 && isdigit((int) argv[i][0])) {
|
||||||
|
xsch_mode=argv[i][0]-'0';
|
||||||
|
if (xsch_mode<=XSCH_GRADIENT) continue;
|
||||||
|
}
|
||||||
|
fprintf(stderr,OPT_USAGE "\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!strcmp(argv[i],"-m")) {
|
||||||
|
if (++i<argc && strlen(argv[i])==1 && isdigit((int) argv[i][0])) {
|
||||||
|
optim_mode=argv[i][0]-'0';
|
||||||
|
if (optim_mode<=OPTIM_DELAY4) continue;
|
||||||
|
}
|
||||||
|
fprintf(stderr,OPT_USAGE "\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*after parameters with options take parameters without '-' */
|
||||||
|
for (i=1; i<argc; i++) {
|
||||||
|
/*skip option*/
|
||||||
|
if (!strcmp(argv[i],"-h") || !strcmp(argv[i],"-o")) continue;
|
||||||
|
/*skip option and argument*/
|
||||||
|
if (!strcmp(argv[i],"-x")
|
||||||
|
|| !strcmp(argv[i],"-l") || !strcmp(argv[i],"-m")) {i++; continue;}
|
||||||
|
/*take file without flag option (order is important)*/
|
||||||
|
if (!input_file || input_file==argv[i]) {input_file=argv[i]; continue;}
|
||||||
|
if (!output_file || output_file==argv[i]) {output_file=argv[i]; continue;}
|
||||||
|
if (!lax_file || lax_file==argv[i]) {lax_file=argv[i]; continue;}
|
||||||
|
fprintf(stderr,OPT_USAGE "\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*extension netlist file (vst or al)*/
|
||||||
|
mbk_in_lo=mbkgetenv ("MBK_IN_LO");
|
||||||
|
if (mbk_in_lo) fprintf(stdout,"\tMBK_IN_LO\t: %s\n",mbk_in_lo);
|
||||||
|
else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Environment Error: no 'MBK_IN_LO' defined for <input_file> extension\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
mbk_out_lo=mbkgetenv ("MBK_OUT_LO");
|
||||||
|
if (mbk_out_lo) fprintf(stdout,"\tMBK_OUT_LO\t: %s\n",mbk_out_lo);
|
||||||
|
else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Environment Error: no 'MBK_OUT_LO' defined for <output_file> extension\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if no library defined*/
|
||||||
|
mbk_target_lib=mbkgetenv ("MBK_TARGET_LIB");
|
||||||
|
if (mbk_target_lib) fprintf(stdout,"\tMBK_TARGET_LIB\t: %s\n",mbk_target_lib);
|
||||||
|
else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Environment Error: no 'MBK_TARGET_LIB' defined for cells directory\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*coherence in options*/
|
||||||
|
if (!input_file) {
|
||||||
|
fprintf(stderr,OPT_USAGE "\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!output_file) {
|
||||||
|
if (overwrite_mode) output_file=input_file;
|
||||||
|
else {
|
||||||
|
fprintf(stderr,OPT_USAGE "\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(output_file,input_file) && !strcmp(mbk_in_lo,mbk_out_lo) && !overwrite_mode) {
|
||||||
|
fprintf(stderr,"<output_file> must be different from <input_file>\n");
|
||||||
|
fprintf(stderr,OPT_USAGE "\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*take default values*/
|
||||||
|
xsch_file=output_file;
|
||||||
|
verbose_mode=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* main LOON */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int main (int argc, char* argv[])
|
||||||
|
{
|
||||||
|
lofig_list *lofig;
|
||||||
|
ptype_list *long_path=NULL;
|
||||||
|
|
||||||
|
/*init*/
|
||||||
|
mbkenv(); /*mbk*/
|
||||||
|
ablenv(); /*abl*/
|
||||||
|
autenv(); /*hash table*/
|
||||||
|
bddenv(); /*for vhdlloadbefig() in library reader*/
|
||||||
|
|
||||||
|
|
||||||
|
alliancebanner_with_authors("LooN", VERSION " [2001/08/21]", "Local optimization on Nets",
|
||||||
|
"2000", "5.0"/*alliance version*/, "François Donnet");
|
||||||
|
|
||||||
|
/*set options*/
|
||||||
|
set_param(argc,argv);
|
||||||
|
|
||||||
|
/*clear*/
|
||||||
|
fprintf(stdout,"\n");
|
||||||
|
|
||||||
|
/*read lax parameter first*/
|
||||||
|
if (lax_file) {
|
||||||
|
fprintf(stdout,"Reading parameter file '%s.lax'...\n",lax_file);
|
||||||
|
parsefilelax(lax_file);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stdout,"Reading default parameter...\n");
|
||||||
|
defaultlax(optim_mode);
|
||||||
|
}
|
||||||
|
switch (getoptimlax()) {
|
||||||
|
case OPTIM_DELAY0: fprintf(stdout,"100%% area optimization\n"); break;
|
||||||
|
case OPTIM_DELAY1:
|
||||||
|
fprintf(stdout,"75%% area - 25%% delay optimization\n"); break;
|
||||||
|
case OPTIM_DELAY2:
|
||||||
|
fprintf(stdout,"50%% area - 50%% delay optimization\n"); break;
|
||||||
|
case OPTIM_DELAY3:
|
||||||
|
fprintf(stdout,"25%% area - 75%% delay optimization\n"); break;
|
||||||
|
case OPTIM_DELAY4: fprintf(stdout,"100%% delay optimization\n"); break;
|
||||||
|
default: fprintf(stderr,"LAX: Optimization mode greater than 4\n"); exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*read vst*/
|
||||||
|
fprintf(stdout,"Reading file '%s.%s'...\n",input_file,mbk_in_lo);
|
||||||
|
lofig=getlofig(input_file, 'A'/*all the figure*/);
|
||||||
|
if (!lofig) {
|
||||||
|
fprintf(stderr,"Cannot find '%s.%s'\n",input_file,mbk_in_lo);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*flatten all instance at cells level*/
|
||||||
|
rflattenlofig(lofig, YES, YES);
|
||||||
|
|
||||||
|
|
||||||
|
/*check coherence between LAX and lofig*/
|
||||||
|
if (lax_file) {
|
||||||
|
fprintf(stdout,"Controlling file '%s.lax'...\n",lax_file);
|
||||||
|
if (!coherencelax(lofig)) exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*read cell library*/
|
||||||
|
fprintf(stdout,"Reading lib '%s'...\n",mbk_target_lib);
|
||||||
|
library_reader(mbk_target_lib);
|
||||||
|
|
||||||
|
|
||||||
|
/*set signal properties*/
|
||||||
|
fprintf(stdout,"Capacitances on file '%s.%s'...\n",input_file,mbk_in_lo);
|
||||||
|
if (!lofig->LOINS || !lofig->LOSIG) {
|
||||||
|
fprintf(stderr,"Figure '%s' is empty!\n",lofig->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*prepare source*/
|
||||||
|
lofigchain(lofig);
|
||||||
|
set_circuit_capacitance(lofig);
|
||||||
|
fprintf(stdout,"Delays on file '%s.%s'...",input_file,mbk_in_lo);
|
||||||
|
fflush(stdout);
|
||||||
|
set_circuit_delay(lofig);
|
||||||
|
fprintf(stdout,"%ld ps\n",(long) critical_delay(lofig));
|
||||||
|
|
||||||
|
/*eval area*/
|
||||||
|
if (verbose_mode) {
|
||||||
|
ptype_list* ptype, *ptype2, *old_percentage, *old_model;
|
||||||
|
|
||||||
|
fprintf(stdout,"Area on file '%s.%s'...",input_file,mbk_in_lo);
|
||||||
|
fflush(stdout);
|
||||||
|
old_model=count_instance(lofig);
|
||||||
|
old_percentage=percent_instance(old_model);
|
||||||
|
fprintf(stdout,"%ld lamda² (with over-cell routing)\n",getarea(lofig));
|
||||||
|
|
||||||
|
/*Details of use*/
|
||||||
|
if (!old_model) fprintf(stdout,"No instance...\n");
|
||||||
|
else {
|
||||||
|
fprintf(stdout,"Details...\n");
|
||||||
|
ptype2=old_percentage;
|
||||||
|
for (ptype=old_model; ptype; ptype=ptype->NEXT) {
|
||||||
|
fprintf(stdout,"\t%s: %ld (%ld%%)\n",(char*)ptype->DATA,
|
||||||
|
ptype->TYPE,ptype2->TYPE);
|
||||||
|
ptype2=ptype2->NEXT;
|
||||||
|
}
|
||||||
|
fprintf(stdout,"\tTotal: %ld\n",getnum_ins(lofig));
|
||||||
|
}
|
||||||
|
freeptype(old_model);
|
||||||
|
freeptype(old_percentage);
|
||||||
|
|
||||||
|
fprintf(stdout,"Worst RC on file '%s.%s'...",input_file,mbk_in_lo);
|
||||||
|
fflush(stdout);
|
||||||
|
fprintf(stdout,"%ld ps\n",(long) getmaxRC(lofig));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*inserting buffer on critical path*/
|
||||||
|
if (getoptimlax()>=OPTIM_DELAY2) {
|
||||||
|
int buffers;
|
||||||
|
fprintf(stdout,"Inserting buffers on critical path for file '%s.%s'...",
|
||||||
|
output_file,mbk_out_lo);
|
||||||
|
fflush(stdout);
|
||||||
|
buffers=insert_buffer_critical_path(lofig,getoptimlax());
|
||||||
|
if (buffers==0) fprintf(stdout,"None inserted\n");
|
||||||
|
else if (buffers==1) fprintf(stdout,"%d buffer inserted -> %ld ps\n",
|
||||||
|
buffers,(long) critical_delay(lofig));
|
||||||
|
else fprintf(stdout,"%d buffers inserted -> %ld ps\n",
|
||||||
|
buffers,(long) critical_delay(lofig));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*improve RC*/
|
||||||
|
fprintf(stdout,"Improving RC on critical path for file '%s.%s'...",
|
||||||
|
output_file,mbk_out_lo);
|
||||||
|
fflush(stdout);
|
||||||
|
improve_capa_critical_path(lofig,getoptimlax());
|
||||||
|
fprintf(stdout,"%ld ps\n",(long) critical_delay(lofig));
|
||||||
|
|
||||||
|
|
||||||
|
/*global optimization*/
|
||||||
|
fprintf(stdout,"Improving all RC for file '%s.%s'...\n",
|
||||||
|
output_file,mbk_out_lo);
|
||||||
|
fprintf(stdout,"Worst RC on file '%s.%s'...",output_file,mbk_out_lo);
|
||||||
|
fflush(stdout);
|
||||||
|
fprintf(stdout,"%ld ps\n",(long) getmaxRC(lofig));
|
||||||
|
|
||||||
|
|
||||||
|
/*saving file*/
|
||||||
|
if (output_file) {
|
||||||
|
fprintf(stdout,"Saving file '%s.%s'...\n",output_file,mbk_out_lo);
|
||||||
|
lofig->NAME=output_file;
|
||||||
|
savelofig(lofig); /*change la lofigchain en mode .al*/
|
||||||
|
lofigchain(lofig);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (verbose_mode) {
|
||||||
|
ptype_list* ptype, *ptype2, *new_percentage, *new_model;
|
||||||
|
losig_list* losig;
|
||||||
|
locon_list* locon;
|
||||||
|
chain_list* lofigchain;
|
||||||
|
loins_list* loins;
|
||||||
|
|
||||||
|
/*eval area*/
|
||||||
|
fprintf(stdout,"Area on file '%s.%s'...",output_file,mbk_out_lo);
|
||||||
|
fflush(stdout);
|
||||||
|
new_model=count_instance(lofig);
|
||||||
|
new_percentage=percent_instance(new_model);
|
||||||
|
fprintf(stdout,"%ld lamda² (with over-cell routing)\n",getarea(lofig));
|
||||||
|
|
||||||
|
/*Details of use*/
|
||||||
|
if (!new_model) fprintf(stdout,"No instance...\n");
|
||||||
|
else {
|
||||||
|
fprintf(stdout,"Details...\n");
|
||||||
|
ptype2=new_percentage;
|
||||||
|
for (ptype=new_model; ptype; ptype=ptype->NEXT) {
|
||||||
|
fprintf(stdout,"\t%s: %ld (%ld%%)\n",(char*)ptype->DATA,
|
||||||
|
ptype->TYPE,ptype2->TYPE);
|
||||||
|
ptype2=ptype2->NEXT;
|
||||||
|
}
|
||||||
|
fprintf(stdout,"\tTotal: %ld\n",getnum_ins(lofig));
|
||||||
|
}
|
||||||
|
freeptype(new_model);
|
||||||
|
freeptype(new_percentage);
|
||||||
|
|
||||||
|
|
||||||
|
/*get list of signal in critical path*/
|
||||||
|
long_path=critical_path_without_clock(lofig);
|
||||||
|
if (long_path) {
|
||||||
|
losig=long_path->DATA;
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"main: no name on signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fprintf(stdout,"Critical path (no warranty)...%ld ps from '%s' to ",
|
||||||
|
(long) critical_delay(lofig),(char*) losig->NAMECHAIN->DATA);
|
||||||
|
fflush(stdout);
|
||||||
|
/*seek last*/
|
||||||
|
for (ptype=long_path; ptype->NEXT; ptype=ptype->NEXT) ;
|
||||||
|
losig=(losig_list*) ptype->DATA;
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"main: no name on signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (losig->TYPE==EXTERNAL) {
|
||||||
|
fprintf(stdout,"'%s'\n",(char*) losig->NAMECHAIN->DATA);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*it is a register entry, search name of the register*/
|
||||||
|
ptype=getptype(losig->USER,LOFIGCHAIN);
|
||||||
|
for (lofigchain=ptype->DATA; lofigchain;
|
||||||
|
lofigchain=lofigchain->NEXT) {
|
||||||
|
locon=lofigchain->DATA;
|
||||||
|
if (locon->DIRECTION==IN) {
|
||||||
|
loins=locon->ROOT;
|
||||||
|
fprintf(stdout,"'%s'\n", loins->INSNAME);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*colors and weight informations for xsch alliance displayer*/
|
||||||
|
if (xsch_file) {
|
||||||
|
FILE* xsch_stream;
|
||||||
|
ptype_list* ptype;
|
||||||
|
char* signame;
|
||||||
|
losig_list* losig;
|
||||||
|
|
||||||
|
switch (xsch_mode) {
|
||||||
|
case XSCH_GRADIENT:
|
||||||
|
fprintf(stdout,
|
||||||
|
"Saving delay gradient in xsch color file '%s.xsc'...\n",xsch_file);
|
||||||
|
break;
|
||||||
|
case XSCH_CRITICAL_PATH: default:
|
||||||
|
fprintf(stdout,
|
||||||
|
"Saving critical path in xsch color file '%s.xsc'...\n",xsch_file);
|
||||||
|
}
|
||||||
|
xsch_stream=mbkfopen(xsch_file,"xsc",WRITE_TEXT);
|
||||||
|
if (!xsch_stream){
|
||||||
|
fprintf(stderr,"Cannot save file %s.xsc\n",xsch_file);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*replace losig by names*/
|
||||||
|
for (ptype=long_path; ptype; ptype=ptype->NEXT) {
|
||||||
|
losig=(losig_list*) ptype->DATA;
|
||||||
|
signame=losig->NAMECHAIN->DATA;
|
||||||
|
ptype->DATA=signame;
|
||||||
|
}
|
||||||
|
save_xsch(xsch_stream,lofig,long_path,xsch_mode);
|
||||||
|
fclose(xsch_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fprintf(stdout,"End of %s...\n\n",LOON);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,592 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - control and simplify acyclic graph
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <mut.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include "lon_lax_param.h"
|
||||||
|
#include "lon_normalize_message.h"
|
||||||
|
#include "lon_normalize_DAG.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define USING(node) {(int)node=-mark;}
|
||||||
|
#define USED(node) {(int)node=(int)((((int)node<0)?0:(int)node)+1);}
|
||||||
|
#define IS_USING(node) ((int)node==-mark)
|
||||||
|
#define IS_USED(node) ((int)node!=0)
|
||||||
|
#define IS_UNUSED(node) ((int)node==0)
|
||||||
|
#define IS_ONE(node) ((int)node==1)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct equi {
|
||||||
|
struct equi *NEXT;
|
||||||
|
char *NAME; /*name of signal to replace*/
|
||||||
|
chain_list *ABL;
|
||||||
|
} equi_list;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static equi_list* EQUI; /*list of replacing abl*/
|
||||||
|
static befig_list *befig; /*the figure to check*/
|
||||||
|
static char* CYCLE; /*name of signal when there is a cycle*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* free memory for delay */
|
||||||
|
/***************************************************************************/
|
||||||
|
static void free_equi(equi_list* equi)
|
||||||
|
{
|
||||||
|
if (!equi) return;
|
||||||
|
free_equi(equi->NEXT);
|
||||||
|
freeablexpr(equi->ABL);
|
||||||
|
mbkfree(equi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* take from the heap */
|
||||||
|
/***************************************************************************/
|
||||||
|
static equi_list* newequi()
|
||||||
|
{
|
||||||
|
equi_list* new;
|
||||||
|
|
||||||
|
new=(equi_list*) mbkalloc(sizeof(equi_list));
|
||||||
|
|
||||||
|
/*fill signal*/
|
||||||
|
new->NEXT=NULL; /*not to interfer with below*/
|
||||||
|
new->ABL=NULL;
|
||||||
|
new->NAME=NULL;
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* memorize equipotential */
|
||||||
|
/******************************************************************************/
|
||||||
|
static void addequi(char* name, chain_list* abl)
|
||||||
|
{
|
||||||
|
equi_list* new;
|
||||||
|
|
||||||
|
new=newequi();
|
||||||
|
new->NEXT=EQUI;
|
||||||
|
new->NAME=name;
|
||||||
|
new->ABL=abl;
|
||||||
|
EQUI=new;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* replace connections between equipotentials */
|
||||||
|
/******************************************************************************/
|
||||||
|
static chain_list* inter_equi(equi_list *equi, chain_list *abl)
|
||||||
|
{
|
||||||
|
chain_list* head;
|
||||||
|
|
||||||
|
if (ABL_ATOM(abl)) {
|
||||||
|
if (equi->NAME==ABL_ATOM_VALUE(abl)) {
|
||||||
|
/*remove equi*/
|
||||||
|
freeablexpr(abl);
|
||||||
|
abl=dupablexpr(equi->ABL);
|
||||||
|
return abl;
|
||||||
|
}
|
||||||
|
return abl;
|
||||||
|
}
|
||||||
|
|
||||||
|
head=abl;
|
||||||
|
for (abl=ABL_CDR(head); abl; abl=ABL_CDR(abl)) {
|
||||||
|
ABL_CAR(abl)=inter_equi(equi,ABL_CAR(abl));
|
||||||
|
}
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* replace equipotential with real signal name */
|
||||||
|
/******************************************************************************/
|
||||||
|
static chain_list* replace_equi(chain_list* abl)
|
||||||
|
{
|
||||||
|
chain_list* head;
|
||||||
|
equi_list* equi;
|
||||||
|
|
||||||
|
if (ABL_ATOM(abl)) {
|
||||||
|
for (equi=EQUI; equi; equi=equi->NEXT) {
|
||||||
|
if (equi->NAME==ABL_ATOM_VALUE(abl)) {
|
||||||
|
/*remove equi*/
|
||||||
|
freeablexpr(abl);
|
||||||
|
abl=dupablexpr(equi->ABL);
|
||||||
|
return abl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return abl;
|
||||||
|
}
|
||||||
|
|
||||||
|
head=abl;
|
||||||
|
for (abl=ABL_CDR(head); abl; abl=ABL_CDR(abl)) {
|
||||||
|
ABL_CAR(abl)=replace_equi(ABL_CAR(abl));
|
||||||
|
}
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* remove unused beaux */
|
||||||
|
/******************************************************************************/
|
||||||
|
static void refresh_signal()
|
||||||
|
{
|
||||||
|
bereg_list* bereg;
|
||||||
|
beout_list* beout;
|
||||||
|
bebux_list* bebux;
|
||||||
|
bebus_list* bebus;
|
||||||
|
beaux_list* beaux;
|
||||||
|
biabl_list* biabl;
|
||||||
|
|
||||||
|
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
|
||||||
|
if (!EQUI) break;
|
||||||
|
for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
if (!EQUI) break;
|
||||||
|
biabl->CNDABL=replace_equi(biabl->CNDABL);
|
||||||
|
biabl->VALABL=replace_equi(biabl->VALABL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
|
||||||
|
if (!EQUI) break;
|
||||||
|
beout->ABL=replace_equi(beout->ABL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
|
||||||
|
if (!EQUI) break;
|
||||||
|
for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
if (!EQUI) break;
|
||||||
|
biabl->CNDABL=replace_equi(biabl->CNDABL);
|
||||||
|
biabl->VALABL=replace_equi(biabl->VALABL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
|
||||||
|
if (!EQUI) break;
|
||||||
|
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
if (!EQUI) break;
|
||||||
|
biabl->CNDABL=replace_equi(biabl->CNDABL);
|
||||||
|
biabl->VALABL=replace_equi(biabl->VALABL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
|
||||||
|
if (!EQUI) break;
|
||||||
|
beaux->ABL=replace_equi(beaux->ABL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* unmark all and erase all unused beaux,bebux */
|
||||||
|
/****************************************************************************/
|
||||||
|
static void unmark_all()
|
||||||
|
{
|
||||||
|
bebus_list *bebus;
|
||||||
|
beout_list *beout;
|
||||||
|
beaux_list *beaux, *pred_beaux=NULL;
|
||||||
|
bebux_list *bebux, *pred_bebux=NULL;
|
||||||
|
bereg_list *bereg, *pred_bereg=NULL;
|
||||||
|
|
||||||
|
|
||||||
|
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
|
||||||
|
beout->NODE=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
|
||||||
|
bebus->BINODE=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bebux=befig->BEBUX; bebux; ) {
|
||||||
|
if (IS_USED(bebux->BINODE)) {
|
||||||
|
bebux->BINODE=NULL;
|
||||||
|
pred_bebux=bebux;
|
||||||
|
bebux=bebux->NEXT;
|
||||||
|
}
|
||||||
|
else { /*bebux isn't used by any output -> erase it*/
|
||||||
|
fprintf(stderr,"BEH: bus '%s' unused\n",bebux->NAME);
|
||||||
|
if (signalsavelax(bebux->NAME)) {
|
||||||
|
/*user doesn't want his signal been erased*/
|
||||||
|
bebux->BINODE=NULL;
|
||||||
|
pred_bebux=bebux;
|
||||||
|
bebux=bebux->NEXT;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pred_bebux) pred_bebux->NEXT=bebux->NEXT;
|
||||||
|
else befig->BEBUX=bebux->NEXT;
|
||||||
|
bebux->NEXT=NULL; /*break recursivity of beh_frebebux() */
|
||||||
|
beh_frebebux(bebux);
|
||||||
|
/*change index for loop*/
|
||||||
|
if (pred_bebux) bebux=pred_bebux->NEXT;
|
||||||
|
else bebux=befig->BEBUX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bereg=befig->BEREG; bereg; ) {
|
||||||
|
if (IS_USED(bereg->BINODE)) {
|
||||||
|
bereg->BINODE=NULL;
|
||||||
|
pred_bereg=bereg;
|
||||||
|
bereg=bereg->NEXT;
|
||||||
|
}
|
||||||
|
else { /*bereg isn't used by any output -> erase it*/
|
||||||
|
fprintf(stderr,"BEH: register '%s' unused\n",bereg->NAME);
|
||||||
|
if (signalsavelax(bereg->NAME)) {
|
||||||
|
/*user doesn't want his signal been erased*/
|
||||||
|
bereg->BINODE=NULL;
|
||||||
|
pred_bereg=bereg;
|
||||||
|
bereg=bereg->NEXT;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pred_bereg) pred_bereg->NEXT=bereg->NEXT;
|
||||||
|
else befig->BEREG=bereg->NEXT;
|
||||||
|
bereg->NEXT=NULL; /*break recursivity of beh_frebereg() */
|
||||||
|
beh_frebereg(bereg);
|
||||||
|
/*change index for loop*/
|
||||||
|
if (pred_bereg) bereg=pred_bereg->NEXT;
|
||||||
|
else bereg=befig->BEREG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (beaux=befig->BEAUX; beaux; ) {
|
||||||
|
if (IS_USED(beaux->NODE) && !IS_ONE(beaux->NODE)
|
||||||
|
&& !ABL_ATOM(beaux->ABL)) {
|
||||||
|
beaux->NODE=NULL;
|
||||||
|
pred_beaux=beaux;
|
||||||
|
beaux=beaux->NEXT;
|
||||||
|
}
|
||||||
|
else { /*beaux isn't used by any output -> erase it*/
|
||||||
|
if (signalsavelax(beaux->NAME)) {
|
||||||
|
/*user does not want his signal been erased*/
|
||||||
|
beaux->NODE=NULL;
|
||||||
|
pred_beaux=beaux;
|
||||||
|
beaux=beaux->NEXT;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (IS_ONE(beaux->NODE) || ABL_ATOM(beaux->ABL)) {
|
||||||
|
/*used only one time or equipotential*/
|
||||||
|
addequi(beaux->NAME,beaux->ABL);
|
||||||
|
beaux->ABL=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*remove*/
|
||||||
|
if (pred_beaux) pred_beaux->NEXT=beaux->NEXT;
|
||||||
|
else befig->BEAUX=beaux->NEXT;
|
||||||
|
beaux->NEXT=NULL; /*break recursivity of beh_frebeaux() */
|
||||||
|
beh_frebeaux(beaux);
|
||||||
|
/*change index for loop*/
|
||||||
|
if (pred_beaux) beaux=pred_beaux->NEXT;
|
||||||
|
else beaux=befig->BEAUX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* mark and follow the tree of abl */
|
||||||
|
/* return 1 if correct abl */
|
||||||
|
/******************************************************************************/
|
||||||
|
static int abl_dispatching(chain_list *abl, int mark)
|
||||||
|
{
|
||||||
|
bebux_list *bebux;
|
||||||
|
beaux_list *beaux;
|
||||||
|
bereg_list *bereg;
|
||||||
|
bepor_list *bepor;
|
||||||
|
beout_list *beout;
|
||||||
|
bebus_list *bebus;
|
||||||
|
biabl_list *biabl;
|
||||||
|
ptype_list* ptype;
|
||||||
|
|
||||||
|
|
||||||
|
if (!abl) {
|
||||||
|
fprintf(stderr,"abl_dispatching: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ABL_ATOM(abl)) { /*it is a leaf*/
|
||||||
|
if (ABL_ATOM_VALUE(abl)==getablatomone() /* '1' */||
|
||||||
|
ABL_ATOM_VALUE(abl)==getablatomzero() /* '0' */||
|
||||||
|
ABL_ATOM_VALUE(abl)==getablatomdc() /* 'd' */ ||
|
||||||
|
ABL_ATOM_VALUE(abl)==getablatomtristate() /* 'z' */) return 1;
|
||||||
|
|
||||||
|
/*search this leaf*/
|
||||||
|
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
|
||||||
|
if (ABL_ATOM_VALUE(abl)==beaux->NAME) {
|
||||||
|
if (IS_USING(beaux->NODE)) {
|
||||||
|
CYCLE=beaux->NAME;
|
||||||
|
fprintf(stderr,"BEH: cycle detected on %s, ",beaux->NAME);
|
||||||
|
fflush(stderr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (IS_USED(beaux->NODE)) {
|
||||||
|
USED(beaux->NODE);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
USING(beaux->NODE);
|
||||||
|
if (!abl_dispatching(beaux->ABL, mark)) {
|
||||||
|
if (!CYCLE) return 0; /*for display*/
|
||||||
|
if (CYCLE==beaux->NAME) {
|
||||||
|
CYCLE=NULL;
|
||||||
|
fprintf(stderr,"%s\n",beaux->NAME);
|
||||||
|
}
|
||||||
|
else fprintf(stderr,"%s, ",beaux->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
USED(beaux->NODE);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
|
||||||
|
if (ABL_ATOM_VALUE(abl)==bebux->NAME) {
|
||||||
|
if (IS_USING(bebux->BINODE)) {
|
||||||
|
CYCLE=bebux->NAME;
|
||||||
|
fprintf(stderr,"BEH: cycle detected on %s, ",bebux->NAME);
|
||||||
|
fflush(stderr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (IS_USED(bebux->BINODE)) {
|
||||||
|
USED(bebux->BINODE);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
USING(bebux->BINODE);
|
||||||
|
for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
if (!abl_dispatching(biabl->CNDABL, mark)
|
||||||
|
|| !abl_dispatching(biabl->VALABL, mark)) {
|
||||||
|
if (!CYCLE) return 0; /*for display*/
|
||||||
|
if (CYCLE==bebux->NAME) {
|
||||||
|
CYCLE=NULL;
|
||||||
|
fprintf(stderr,"%s\n",bebux->NAME);
|
||||||
|
}
|
||||||
|
else fprintf(stderr,"%s, ",bebux->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
USED(bebux->BINODE);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
|
||||||
|
if (ABL_ATOM_VALUE(abl)==bereg->NAME) {
|
||||||
|
if (IS_USING(bereg->BINODE)) {
|
||||||
|
CYCLE=bereg->NAME;
|
||||||
|
fprintf(stderr,"BEH: cycle detected on %s, ",bereg->NAME);
|
||||||
|
fflush(stderr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (IS_USED(bereg->BINODE)) {
|
||||||
|
USED(bereg->BINODE);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*cycle forbidden on clock*/
|
||||||
|
USING(bereg->BINODE);
|
||||||
|
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
ptype=getptype(biabl->USER,ABL_STABLE); /*search if flip-flop*/
|
||||||
|
/*cycle not forbidden on value for flip-flop */
|
||||||
|
/*but forbidden for latch*/
|
||||||
|
if (!abl_dispatching(biabl->CNDABL, mark)
|
||||||
|
|| (!ptype && !abl_dispatching(biabl->VALABL, mark))
|
||||||
|
|| (ptype && !abl_dispatching(biabl->VALABL, mark+1))) {
|
||||||
|
if (!CYCLE) return 0; /*for display*/
|
||||||
|
if (CYCLE==bereg->NAME) {
|
||||||
|
CYCLE=NULL;
|
||||||
|
fprintf(stderr,"%s\n",bereg->NAME);
|
||||||
|
}
|
||||||
|
else fprintf(stderr,"%s, ",bereg->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
USED(bereg->BINODE);
|
||||||
|
/*impossible to look after value now, probably cycled on a signal*/
|
||||||
|
/*wait the end of recursion*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*control cycle on inout port*/
|
||||||
|
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
|
||||||
|
if (ABL_ATOM_VALUE(abl)==beout->NAME) {
|
||||||
|
if (IS_USING(beout->NODE)) {
|
||||||
|
CYCLE=beout->NAME;
|
||||||
|
fprintf(stderr,"BEH: cycle detected on %s, ",beout->NAME);
|
||||||
|
fflush(stderr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*control cycle on inout bus port*/
|
||||||
|
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
|
||||||
|
if (ABL_ATOM_VALUE(abl)==bebus->NAME) {
|
||||||
|
if (IS_USING(bebus->BINODE)) {
|
||||||
|
CYCLE=bebus->NAME;
|
||||||
|
fprintf(stderr,"BEH: cycle detected on %s, ",bebus->NAME);
|
||||||
|
fflush(stderr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*is it input?*/
|
||||||
|
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
|
||||||
|
if (bepor->DIRECTION!=IN && bepor->DIRECTION!=INOUT
|
||||||
|
&& bepor->DIRECTION!=TRANSCV) continue;
|
||||||
|
if (bepor->NAME==ABL_ATOM_VALUE(abl)) return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*error: leaf not found*/
|
||||||
|
fprintf(stderr,"abl_dispatching: %s not found\n",ABL_ATOM_VALUE(abl));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*it is an operator*/
|
||||||
|
for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) {
|
||||||
|
/*define each leaf*/
|
||||||
|
if (!abl_dispatching(ABL_CAR(abl)/*abl study*/, mark)) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1; /*ok*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* mark each output */
|
||||||
|
/* return 1 if correct */
|
||||||
|
/***************************************************************************/
|
||||||
|
static int mark_output()
|
||||||
|
{
|
||||||
|
bebus_list *bebus;
|
||||||
|
beout_list *beout;
|
||||||
|
biabl_list *biabl;
|
||||||
|
int mark=1;
|
||||||
|
|
||||||
|
/*create new internal signals and mark the path from output to input*/
|
||||||
|
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
|
||||||
|
USING(beout->NODE);
|
||||||
|
if (!abl_dispatching(beout->ABL, mark)) {
|
||||||
|
if (!CYCLE) return 0; /*for display*/
|
||||||
|
if (CYCLE==beout->NAME) {
|
||||||
|
CYCLE=NULL;
|
||||||
|
fprintf(stderr,"%s\n",beout->NAME);
|
||||||
|
}
|
||||||
|
else fprintf(stderr,"%s, ",beout->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
USED(beout->NODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
|
||||||
|
USING(bebus->BINODE);
|
||||||
|
for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
if (!abl_dispatching(biabl->CNDABL, mark)
|
||||||
|
|| !abl_dispatching(biabl->VALABL, mark)) {
|
||||||
|
if (!CYCLE) return 0; /*for display*/
|
||||||
|
if (CYCLE==bebus->NAME) {
|
||||||
|
CYCLE=NULL;
|
||||||
|
fprintf(stderr,"%s\n",bebus->NAME);
|
||||||
|
}
|
||||||
|
else fprintf(stderr,"%s, ",bebus->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
USED(bebus->BINODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1; /*ok*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* control cycles in befig and erase unused internal signal */
|
||||||
|
/* return 1 if correct befig */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int DAG_control(befig_list *befig_param)
|
||||||
|
{
|
||||||
|
equi_list* equi, *equi2;
|
||||||
|
bereg_list *bereg;
|
||||||
|
bebus_list *bebus;
|
||||||
|
bebux_list *bebux;
|
||||||
|
|
||||||
|
if (!befig_param) {
|
||||||
|
fprintf(stderr,"DAG_control: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
befig=befig_param;
|
||||||
|
EQUI=NULL;
|
||||||
|
CYCLE=NULL; /*name of signal*/
|
||||||
|
|
||||||
|
/*erase binode*/
|
||||||
|
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
|
||||||
|
beh_frebinode(bereg->BINODE);
|
||||||
|
bereg->BINODE=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
|
||||||
|
beh_frebinode(bebus->BINODE);
|
||||||
|
bebus->BINODE=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
|
||||||
|
beh_frebinode(bebux->BINODE);
|
||||||
|
bebux->BINODE=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*begin by output*/
|
||||||
|
if (!mark_output()) return 0;
|
||||||
|
|
||||||
|
/*unmark and erase unused*/
|
||||||
|
unmark_all();
|
||||||
|
|
||||||
|
/*maybe cyclical reference in abl*/
|
||||||
|
for (equi=EQUI; equi; equi=equi->NEXT) {
|
||||||
|
for (equi2=EQUI; equi2; equi2=equi2->NEXT) {
|
||||||
|
equi2->ABL=inter_equi(equi,equi2->ABL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*insert equipotential*/
|
||||||
|
refresh_signal();
|
||||||
|
free_equi(EQUI);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - control and simplify acyclic graph
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NORMALIZE_DAG_H
|
||||||
|
#define NORMALIZE_DAG_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* control cycles in befig and erase unused internal signal */
|
||||||
|
/* return 1 if correct befig */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int DAG_control __P ((befig_list *befig));
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - display message
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <mut.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include "lon_normalize_message.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* display an abl tree */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void display_abl(chain_list* abl)
|
||||||
|
{
|
||||||
|
static int first=1; /*flags for braces*/
|
||||||
|
int sig_first=0;
|
||||||
|
int oper;
|
||||||
|
|
||||||
|
if (!abl) {
|
||||||
|
fprintf (stderr,"(null)");
|
||||||
|
fflush(stderr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ABL_ATOM (abl)) { /* Traitement atomique */
|
||||||
|
fprintf (stderr,"%s", ABL_ATOM_VALUE (abl));
|
||||||
|
fflush(stderr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
oper=ABL_OPER(abl); /*memorisation de l'operateur*/
|
||||||
|
|
||||||
|
/*operateur unaire*/
|
||||||
|
switch (oper) {
|
||||||
|
case ABL_NOT:
|
||||||
|
fprintf (stderr,"%s ",getabloperuppername(oper));
|
||||||
|
fflush(stderr);
|
||||||
|
display_abl (ABL_CADR (abl));
|
||||||
|
return;
|
||||||
|
case ABL_STABLE:
|
||||||
|
display_abl (ABL_CADR (abl));
|
||||||
|
fprintf (stderr," %s",getabloperuppername(oper));
|
||||||
|
fflush(stderr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*need of brace?*/
|
||||||
|
if (first) {first=0; sig_first=1;}
|
||||||
|
else fprintf (stderr,"(");
|
||||||
|
fflush(stderr);
|
||||||
|
|
||||||
|
/* Traitement des autres operateurs */
|
||||||
|
for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) {
|
||||||
|
display_abl(ABL_CAR(abl));
|
||||||
|
/* Un operateur en moins que le nombre d'arguments */
|
||||||
|
if (ABL_CDR (abl)) fprintf (stderr," %s ",getabloperuppername(oper));
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sig_first) first=1;
|
||||||
|
else fprintf(stderr,")");
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* display a message error and an abl */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void display_error_in_abl(char* message, chain_list *abl)
|
||||||
|
{
|
||||||
|
if (!message || !abl) {
|
||||||
|
fprintf(stderr,"display_error_in_abl: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr,"BEH: ");
|
||||||
|
fprintf(stderr,message);
|
||||||
|
fprintf(stderr," in '");
|
||||||
|
fflush(stderr);
|
||||||
|
display_abl(abl);
|
||||||
|
fprintf(stderr,"'\n");
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - display message
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NORMALIZE_MESSAGE_H
|
||||||
|
#define NORMALIZE_MESSAGE_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* display an abl tree */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void display_abl __P ((chain_list* abl));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* display a message error and an abl */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void display_error_in_abl __P ((char* message, chain_list *abl));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - control power supply
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <mut.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include "lon_normalize_power.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* if power supply is found in abl expression generate an error */
|
||||||
|
/* return 1 if no problem encountered */
|
||||||
|
/******************************************************************************/
|
||||||
|
static int power_ok(befig_list* befig, chain_list* abl)
|
||||||
|
{
|
||||||
|
if (ABL_ATOM(abl)) {
|
||||||
|
if (isvdd(ABL_ATOM_VALUE(abl)) || isvss(ABL_ATOM_VALUE(abl))) {
|
||||||
|
fprintf(stderr,"BEH: power '%s' is used in an expression\n",
|
||||||
|
ABL_ATOM_VALUE(abl));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) {
|
||||||
|
if (!power_ok(befig,ABL_CAR(abl))) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1; /*ok*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* detect power and forbid Vdd and Vss in abl expression */
|
||||||
|
/* return 1 if no problem encountered */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int detect_power(befig_list* befig)
|
||||||
|
{
|
||||||
|
bebus_list* bebus;
|
||||||
|
beaux_list* beaux;
|
||||||
|
beout_list* beout;
|
||||||
|
bereg_list* bereg;
|
||||||
|
bebux_list* bebux;
|
||||||
|
biabl_list* biabl;
|
||||||
|
bepor_list* bepor;
|
||||||
|
int vss=0, vdd=0; /*flag for detection*/
|
||||||
|
|
||||||
|
/*search power*/
|
||||||
|
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
|
||||||
|
if (isvdd(bepor->NAME)) {
|
||||||
|
/*only input*/
|
||||||
|
if (bepor->DIRECTION!=IN) {
|
||||||
|
fprintf(stderr,"BEH: '%s: IN bit;' is needed in port of %s\n",
|
||||||
|
bepor->NAME,befig->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (vdd) {
|
||||||
|
fprintf(stderr,"BEH: duplicate Vdd power in port for %s in %s\n",
|
||||||
|
bepor->NAME,befig->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
vdd=1;
|
||||||
|
}
|
||||||
|
else if (isvss(bepor->NAME)) {
|
||||||
|
/*only input*/
|
||||||
|
if (bepor->DIRECTION!=IN) {
|
||||||
|
fprintf(stderr,"BEH: '%s: IN bit;' is needed in port of %s\n",
|
||||||
|
bepor->NAME,befig->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (vss) {
|
||||||
|
fprintf(stderr,"BEH: duplicate Vss power in port for %s in %s\n",
|
||||||
|
bepor->NAME,befig->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
vss=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*power must exist*/
|
||||||
|
if (!vdd || !vss) {
|
||||||
|
fprintf(stderr,"BEH: Vdd and Vss are needed in port of %s\n",befig->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*forbid the use of power in expression*/
|
||||||
|
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
|
||||||
|
if (!power_ok(befig,beout->ABL)) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
|
||||||
|
if (!power_ok(befig,beaux->ABL)) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
|
||||||
|
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
if (!power_ok(befig,biabl->CNDABL)) return 0;
|
||||||
|
if (!power_ok(befig,biabl->VALABL)) return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
|
||||||
|
for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
if (!power_ok(befig,biabl->CNDABL)) return 0;
|
||||||
|
if (!power_ok(befig,biabl->VALABL)) return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
|
||||||
|
for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
if (!power_ok(befig,biabl->CNDABL)) return 0;
|
||||||
|
if (!power_ok(befig,biabl->VALABL)) return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1; /*ok*/
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - control power supply
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NORMALIZE_POWER_H
|
||||||
|
#define NORMALIZE_POWER_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* detect power and forbid Vdd and Vss in abl expression */
|
||||||
|
/* return 1 if no problem encountered */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int detect_power __P ((befig_list* befig));
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,226 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - format flip-flop
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <mut.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include "lon_normalize_message.h"
|
||||||
|
#include "lon_normalize_register.h"
|
||||||
|
|
||||||
|
/*flag if an VHDL error is met*/
|
||||||
|
static int BEH_ERROR;
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* return the number of times ck is found in abl (expect under stable) */
|
||||||
|
/******************************************************************************/
|
||||||
|
static int clock_values(char* ck, chain_list* abl)
|
||||||
|
{
|
||||||
|
int ret=0;
|
||||||
|
|
||||||
|
if (ABL_ATOM(abl)) {
|
||||||
|
if (ABL_ATOM_VALUE(abl)==ck) return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ABL_OPER(abl)==ABL_STABLE) return 0;
|
||||||
|
|
||||||
|
for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) {
|
||||||
|
ret+=clock_values(ck,ABL_CAR(abl));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* extract the clock */
|
||||||
|
/*verify unicity of clock */
|
||||||
|
/******************************************************************************/
|
||||||
|
static char* find_stable(chain_list* abl)
|
||||||
|
{
|
||||||
|
char* ck=NULL, *new;
|
||||||
|
|
||||||
|
/*if it's a leaf, we don't have met a stable at this level*/
|
||||||
|
if (ABL_ATOM(abl)) return NULL;
|
||||||
|
|
||||||
|
if (ABL_OPER(abl)==ABL_STABLE/*ABL library*/) {
|
||||||
|
return ABL_ATOM_VALUE(ABL_CADR(abl));
|
||||||
|
}
|
||||||
|
for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) {
|
||||||
|
new=find_stable(ABL_CAR(abl));
|
||||||
|
if (new) {
|
||||||
|
if (ck) {
|
||||||
|
BEH_ERROR=1;
|
||||||
|
return ck;
|
||||||
|
}
|
||||||
|
ck=new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*not found*/
|
||||||
|
return ck;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* latch, flip-flop, flip-flop with write enable are accepted */
|
||||||
|
/*remove stable and put a PTYPE in BIABL field ABL_STABLE with clock name */
|
||||||
|
/* mute all write enable condition on multiplexor! (only for flip-flop) */
|
||||||
|
/*return 1 if has been formatted */
|
||||||
|
/******************************************************************************/
|
||||||
|
static int loc_format_register(bereg_list* bereg)
|
||||||
|
{
|
||||||
|
char* ck;
|
||||||
|
biabl_list* biabl;
|
||||||
|
chain_list* abl, *pred, *current;
|
||||||
|
|
||||||
|
if (!bereg || !bereg->BIABL) {
|
||||||
|
fprintf(stderr,"identify_register: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*only one condition authorized*/
|
||||||
|
if (bereg->BIABL->NEXT) {
|
||||||
|
fprintf(stderr,"BEH: several conditions aren't accepted on register %s\n",
|
||||||
|
bereg->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*anyway control all condition block*/
|
||||||
|
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
|
||||||
|
/*extract stable variable*/
|
||||||
|
ck=find_stable(biabl->CNDABL);
|
||||||
|
if (BEH_ERROR) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"BEH: Bad usage of stable for register %s\n",bereg->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ck) {/*for flip-flop memorize the clock setup signal*/
|
||||||
|
chain_list *setup=NULL, *not_stable=NULL, *wen=NULL;
|
||||||
|
if (ABL_ATOM(biabl->CNDABL) || ABL_OPER(biabl->CNDABL)!=ABL_AND ||
|
||||||
|
clock_values(ck,biabl->CNDABL)!=1) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"BEH: Clock '%s' setup value isn't explicit for register %s\n",
|
||||||
|
ck,bereg->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*separate clock setup value, stable and write enable*/
|
||||||
|
pred=biabl->CNDABL;
|
||||||
|
for (abl=ABL_CDR(biabl->CNDABL); abl; abl=ABL_CDR(abl)) {
|
||||||
|
current=ABL_CAR(abl);
|
||||||
|
/*clock setup value? ck ..... not ck ..... */
|
||||||
|
if ((ABL_ATOM(current) && ABL_ATOM_VALUE(current)==ck) ||
|
||||||
|
(ABL_OPER(current)==ABL_NOT && ABL_ATOM(ABL_CADR(current))
|
||||||
|
&& ABL_ATOM_VALUE(ABL_CADR(current))==ck)) {
|
||||||
|
/*remove ck from condition expression*/
|
||||||
|
setup=current;
|
||||||
|
pred->NEXT=abl->NEXT;
|
||||||
|
abl->NEXT=NULL;
|
||||||
|
freechain(abl);
|
||||||
|
abl=pred;
|
||||||
|
}
|
||||||
|
else if (!ABL_ATOM(current) && ABL_OPER(current)==ABL_NOT
|
||||||
|
&& !ABL_ATOM(ABL_CADR(current))
|
||||||
|
&& ABL_OPER(ABL_CADR(current))==ABL_STABLE) {
|
||||||
|
/*'not stable ck' remove stable from condition expression*/
|
||||||
|
not_stable=current;
|
||||||
|
pred->NEXT=abl->NEXT;
|
||||||
|
abl->NEXT=NULL;
|
||||||
|
freechain(abl);
|
||||||
|
abl=pred;
|
||||||
|
}
|
||||||
|
pred=abl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*build write enable register and condition without stable*/
|
||||||
|
if (!setup || !not_stable) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"BEH: Clock '%s' setup value isn't explicit for register %s\n",
|
||||||
|
ck,bereg->NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
biabl->USER=addptype(biabl->USER,ABL_STABLE,ck);
|
||||||
|
wen=biabl->CNDABL;
|
||||||
|
biabl->CNDABL=setup;
|
||||||
|
if (!ABL_CDR(wen)) { /* AND -> no wen */
|
||||||
|
freechain(wen);
|
||||||
|
continue; /*DON'T BUILD mux for wen*/
|
||||||
|
}
|
||||||
|
if (!ABL_CDR(ABL_CDR(wen))) { /* AND a -> wen = a */
|
||||||
|
abl=ABL_CADR(wen); /* AND a b -> wen = a AND b */
|
||||||
|
freechain(wen);
|
||||||
|
wen=abl;
|
||||||
|
}
|
||||||
|
abl= createablbinexpr(ABL_AND, createablnotexpr(wen),
|
||||||
|
createablatom(bereg->NAME)); /* (not wen) and reg */
|
||||||
|
biabl->VALABL= createablbinexpr(ABL_AND, dupablexpr(wen),
|
||||||
|
biabl->VALABL); /* wen and val */
|
||||||
|
biabl->VALABL= createablbinexpr(ABL_OR, biabl->VALABL, abl); /*wen!*/
|
||||||
|
}
|
||||||
|
|
||||||
|
} /*theorical loop on condition blocks*/
|
||||||
|
|
||||||
|
return 1; /*ok*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*return 1 if all registers have been formatted */
|
||||||
|
/* verify the condition block and put the clock name in biabl->USER field */
|
||||||
|
/* as ABL_STABLE type */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int format_register(befig_list* befig)
|
||||||
|
{
|
||||||
|
bereg_list* bereg;
|
||||||
|
|
||||||
|
if (!befig) {
|
||||||
|
fprintf(stderr,"format_register: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
BEH_ERROR=0;
|
||||||
|
|
||||||
|
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
|
||||||
|
if (!loc_format_register(bereg)) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1; /*ok: formatted*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - format flip-flop
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NORMALIZE_REGISTER_H
|
||||||
|
#define NORMALIZE_REGISTER_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* latch, flip-flop, flip-flop with write enable are accepted */
|
||||||
|
/*remove stable and put a PTYPE in BIABL field ABL_STABLE with clock name */
|
||||||
|
/* mute all write enable condition on multiplexor! (only for flip-flop) */
|
||||||
|
/*return 1 if has been formatted */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern int format_register __P ((befig_list* befig));
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,247 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - simplify befig expressions
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include "lon_normalize_simplify.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* build binary negativ operators */
|
||||||
|
/***************************************************************************/
|
||||||
|
static chain_list* unflatnegexpr(chain_list* abl)
|
||||||
|
{
|
||||||
|
chain_list *chain;
|
||||||
|
int count=0;
|
||||||
|
|
||||||
|
if (ABL_ATOM(abl)) return abl;
|
||||||
|
|
||||||
|
for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
|
||||||
|
ABL_CAR(chain)=unflatnegexpr(ABL_CAR(chain));
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*already binary NXOR not accepted by parser/driver*/
|
||||||
|
if (ABL_OPER(abl)!=ABL_NXOR && count<=2) return abl;
|
||||||
|
|
||||||
|
switch(ABL_OPER(abl)) {
|
||||||
|
case ABL_NAND:
|
||||||
|
ABL_OPER(abl)=ABL_AND;
|
||||||
|
return createablnotexpr(abl);
|
||||||
|
case ABL_NOR:
|
||||||
|
ABL_OPER(abl)=ABL_OR;
|
||||||
|
return createablnotexpr(abl);
|
||||||
|
case ABL_NXOR:
|
||||||
|
ABL_OPER(abl)=ABL_XOR;
|
||||||
|
return createablnotexpr(abl);
|
||||||
|
default: return abl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* put binary oper to befig to be understood by parser and PROOF (CAO util.) */
|
||||||
|
/* for debugging mode */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void binary_oper(befig_list *befig)
|
||||||
|
{
|
||||||
|
beout_list* beout;
|
||||||
|
bebus_list* bebus;
|
||||||
|
bereg_list* bereg;
|
||||||
|
bebux_list* bebux;
|
||||||
|
beaux_list* beaux;
|
||||||
|
biabl_list* biabl;
|
||||||
|
|
||||||
|
for (beout=befig->BEOUT; beout; beout=beout->NEXT)
|
||||||
|
beout->ABL=unflatnegexpr(beout->ABL);
|
||||||
|
|
||||||
|
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT)
|
||||||
|
beaux->ABL=unflatnegexpr(beaux->ABL);
|
||||||
|
|
||||||
|
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
|
||||||
|
for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
biabl->CNDABL=unflatnegexpr(biabl->CNDABL);
|
||||||
|
biabl->VALABL=unflatnegexpr(biabl->VALABL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
|
||||||
|
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
biabl->CNDABL=unflatnegexpr(biabl->CNDABL);
|
||||||
|
biabl->VALABL=unflatnegexpr(biabl->VALABL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
|
||||||
|
for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
biabl->CNDABL=unflatnegexpr(biabl->CNDABL);
|
||||||
|
biabl->VALABL=unflatnegexpr(biabl->VALABL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* merge operator */
|
||||||
|
/***************************************************************************/
|
||||||
|
static void flattenablexpr(chain_list* abl)
|
||||||
|
{
|
||||||
|
chain_list* leaf, *chain, *last, *pred;
|
||||||
|
|
||||||
|
if (ABL_ATOM(abl)) return;
|
||||||
|
|
||||||
|
for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
|
||||||
|
flattenablexpr(ABL_CAR(chain));
|
||||||
|
}
|
||||||
|
pred=abl;
|
||||||
|
for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
|
||||||
|
leaf=ABL_CAR(chain);
|
||||||
|
if (ABL_ATOM(leaf)) {pred=chain; continue;}
|
||||||
|
|
||||||
|
switch(ABL_OPER(abl)) {
|
||||||
|
case ABL_NAND: case ABL_AND:
|
||||||
|
if (ABL_OPER(leaf)==ABL_AND) {
|
||||||
|
/*seek the last*/
|
||||||
|
for (last=ABL_CDR(leaf); ABL_CDR(last); last=ABL_CDR(last)) ;
|
||||||
|
/*free connections*/
|
||||||
|
ABL_CDR(pred)=ABL_CDR(chain);
|
||||||
|
ABL_CDR(chain)=NULL;
|
||||||
|
freechain(chain);
|
||||||
|
chain=pred;
|
||||||
|
/*insert leaves in abl*/
|
||||||
|
ABL_CDR(last)=ABL_CDR(abl);
|
||||||
|
ABL_CDR(abl)=ABL_CDR(leaf);
|
||||||
|
/*free connections*/
|
||||||
|
ABL_CDR(leaf)=NULL;
|
||||||
|
freechain(leaf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ABL_NOR: case ABL_OR:
|
||||||
|
if (ABL_OPER(leaf)==ABL_OR) {
|
||||||
|
/*seek the last*/
|
||||||
|
for (last=ABL_CDR(leaf); ABL_CDR(last); last=ABL_CDR(last)) ;
|
||||||
|
/*free connections*/
|
||||||
|
ABL_CDR(pred)=ABL_CDR(chain);
|
||||||
|
ABL_CDR(chain)=NULL;
|
||||||
|
freechain(chain);
|
||||||
|
chain=pred;
|
||||||
|
/*insert leaves in abl*/
|
||||||
|
ABL_CDR(last)=ABL_CDR(abl);
|
||||||
|
ABL_CDR(abl)=ABL_CDR(leaf);
|
||||||
|
/*free connections*/
|
||||||
|
ABL_CDR(leaf)=NULL;
|
||||||
|
freechain(leaf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ABL_NXOR: case ABL_XOR:
|
||||||
|
if (ABL_OPER(leaf)==ABL_XOR) {
|
||||||
|
/*seek the last*/
|
||||||
|
for (last=ABL_CDR(leaf); ABL_CDR(last); last=ABL_CDR(last)) ;
|
||||||
|
/*free connections*/
|
||||||
|
ABL_CDR(pred)=ABL_CDR(chain);
|
||||||
|
ABL_CDR(chain)=NULL;
|
||||||
|
freechain(chain);
|
||||||
|
chain=pred;
|
||||||
|
/*insert leaves in abl*/
|
||||||
|
ABL_CDR(last)=ABL_CDR(abl);
|
||||||
|
ABL_CDR(abl)=ABL_CDR(leaf);
|
||||||
|
/*free connections*/
|
||||||
|
ABL_CDR(leaf)=NULL;
|
||||||
|
freechain(leaf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ABL_STABLE: case ABL_NOT: break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"unflattenexprabl: operator %ld unknown\n",
|
||||||
|
ABL_OPER(abl));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
pred=chain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* Simplify the abl of befig */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void simplify_expr(befig_list* befig)
|
||||||
|
{
|
||||||
|
bebus_list* bebus;
|
||||||
|
beaux_list* beaux;
|
||||||
|
beout_list* beout;
|
||||||
|
bereg_list* bereg;
|
||||||
|
bebux_list* bebux;
|
||||||
|
biabl_list* biabl;
|
||||||
|
|
||||||
|
|
||||||
|
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
|
||||||
|
beout->ABL=simpablexpr(beout->ABL);
|
||||||
|
flattenablexpr(beout->ABL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
|
||||||
|
beaux->ABL=simpablexpr(beaux->ABL);
|
||||||
|
flattenablexpr(beaux->ABL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
|
||||||
|
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
biabl->CNDABL=simpablexpr(biabl->CNDABL);
|
||||||
|
biabl->VALABL=simpablexpr(biabl->VALABL);
|
||||||
|
flattenablexpr(biabl->CNDABL);
|
||||||
|
flattenablexpr(biabl->VALABL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
|
||||||
|
for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
biabl->CNDABL=simpablexpr(biabl->CNDABL);
|
||||||
|
biabl->VALABL=simpablexpr(biabl->VALABL);
|
||||||
|
flattenablexpr(biabl->CNDABL);
|
||||||
|
flattenablexpr(biabl->VALABL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
|
||||||
|
for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) {
|
||||||
|
biabl->CNDABL=simpablexpr(biabl->CNDABL);
|
||||||
|
biabl->VALABL=simpablexpr(biabl->VALABL);
|
||||||
|
flattenablexpr(biabl->CNDABL);
|
||||||
|
flattenablexpr(biabl->VALABL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - simplify befig expressions
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NORMALIZE_SIMPLIFY_H
|
||||||
|
#define NORMALIZE_SIMPLIFY_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* put binary oper to befig to be understood by parser and PROOF (CAO util.) */
|
||||||
|
/* for debugging mode */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern void binary_oper __P ((befig_list *befig));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* Simplify the abl of befig */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void simplify_expr __P ((befig_list* befig));
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,621 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - cpapcitance optimization
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <mlu.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include <aut.h>
|
||||||
|
#include "lon_lax_param.h"
|
||||||
|
#include "lon_lib_utils.h"
|
||||||
|
#include "lon_signal_utils.h"
|
||||||
|
#include "lon_signal_name.h"
|
||||||
|
#include "lon_signal_netlist.h"
|
||||||
|
#include "lon_signal_critical.h"
|
||||||
|
#include "lon_optim_capa.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* sort a list of signal in capacitance order */
|
||||||
|
/***************************************************************************/
|
||||||
|
static ptype_list* sort_capa(ptype_list* capa)
|
||||||
|
{
|
||||||
|
ptype_list* ptype, *best=NULL, *pred, *pred_best=NULL;
|
||||||
|
double C, best_C;
|
||||||
|
losig_list* losig;
|
||||||
|
|
||||||
|
if (!capa) return NULL;
|
||||||
|
|
||||||
|
best=capa;
|
||||||
|
losig=(losig_list*) capa->DATA;
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"sort_capa: no name on signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
best_C=getcapacitance(losig->NAMECHAIN->DATA);
|
||||||
|
pred=capa;
|
||||||
|
|
||||||
|
/*seek the greatest*/
|
||||||
|
for (ptype=capa->NEXT; ptype; ptype=ptype->NEXT) {
|
||||||
|
losig=(losig_list*) ptype->DATA;
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"sort_capa: no name on signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
C=getcapacitance((char*) losig->NAMECHAIN->DATA);
|
||||||
|
if (C>best_C) {
|
||||||
|
best=ptype;
|
||||||
|
best_C=C;
|
||||||
|
pred_best=pred;
|
||||||
|
}
|
||||||
|
pred=ptype;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pred_best) pred_best->NEXT=best->NEXT;
|
||||||
|
else capa=capa->NEXT;
|
||||||
|
|
||||||
|
best->NEXT=sort_capa(capa);
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* try to improve timing by changing cell impedance */
|
||||||
|
/* return 1 if replace is successfull */
|
||||||
|
/***************************************************************************/
|
||||||
|
static int change_instance(loins_list* loins, losig_list* losig, lofig_list* lofig, int optim_level)
|
||||||
|
{
|
||||||
|
losig_list* losig_aux;
|
||||||
|
lofig_list* lofig_aux;
|
||||||
|
double critical, best_critical, delay, best_delay;
|
||||||
|
double RC_max, T_max;
|
||||||
|
locon_list* locon, *locon_aux;
|
||||||
|
int change=0;
|
||||||
|
cell_list* cell, *best;
|
||||||
|
|
||||||
|
best=getCell(loins->FIGNAME);
|
||||||
|
if (!best || best->NAME!=loins->FIGNAME) {
|
||||||
|
fprintf(stderr,"library error: no cell '%s.vbe' found\n",loins->FIGNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"change_instance: no name on signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
best_critical=critical_delay(lofig);
|
||||||
|
best_delay=loins_delay(loins,losig->NAMECHAIN->DATA);
|
||||||
|
/*compare RC and delay of instance*/
|
||||||
|
RC_max=loins_max_RC(loins,losig->NAMECHAIN->DATA);
|
||||||
|
T_max=loins_max_T(loins);
|
||||||
|
|
||||||
|
/*check all cell of the same kind*/
|
||||||
|
for (cell=sameCells(loins->FIGNAME); cell; cell=cell->NEXT) {
|
||||||
|
/*eval critical*/
|
||||||
|
loins_capacitance(loins,0); /*remove own capacity*/
|
||||||
|
loins->FIGNAME=cell->NAME; /*change cell*/
|
||||||
|
loins_capacitance(loins,1); /*add its own capacity (cell has changed)*/
|
||||||
|
propagate_loins_delay(loins);
|
||||||
|
critical=critical_delay(lofig);
|
||||||
|
delay=loins_delay(loins,losig->NAMECHAIN->DATA);
|
||||||
|
|
||||||
|
/*take new solution?*/
|
||||||
|
if (
|
||||||
|
(critical<best_critical && (cell->AREA<=best->AREA || optim_level>OPTIM_DELAY0))
|
||||||
|
|| (critical==best_critical && delay<best_delay && (cell->AREA<=best->AREA || optim_level>=OPTIM_DELAY4 || (RC_max>T_max && optim_level>=OPTIM_DELAY1)))
|
||||||
|
|| (critical==best_critical && delay==best_delay && cell->AREA<best->AREA)
|
||||||
|
) {
|
||||||
|
best_critical=critical;
|
||||||
|
best=cell;
|
||||||
|
best_delay=delay;
|
||||||
|
change=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /*end of loop on cell*/
|
||||||
|
|
||||||
|
loins_capacitance(loins,0); /*substract own capacity*/
|
||||||
|
loins->FIGNAME=best->NAME;
|
||||||
|
|
||||||
|
/*capacitance and critical delay*/
|
||||||
|
loins_capacitance(loins,1); /*add it own capacity (cell has changed)*/
|
||||||
|
propagate_loins_delay(loins);
|
||||||
|
|
||||||
|
/*verify change of loins*/
|
||||||
|
critical=critical_delay(lofig);
|
||||||
|
delay=loins_delay(loins,losig->NAMECHAIN->DATA);
|
||||||
|
if ((int)critical!=(int)best_critical || (int)delay!=(int)best_delay) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"change_instance: compute error %f!=%f ps %f!=%f ps (%sdue to caller)\n",
|
||||||
|
critical,best_critical,delay,best_delay,change?"not ":"");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*if cell doesn't exist but is composed by several cells*/
|
||||||
|
/*map port with real order*/
|
||||||
|
if (best->MODE=='A' || best->MODE=='a') {
|
||||||
|
loins_capacitance(loins,0); /*substract own capacity*/
|
||||||
|
/*change names*/
|
||||||
|
loins->FIGNAME=best->BEFIG->NAME;
|
||||||
|
lofig_aux=getlofig(best->NAME,'A');
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
/*search locon in model*/
|
||||||
|
for (locon_aux=lofig_aux->LOCON; locon_aux; locon_aux=locon_aux->NEXT){
|
||||||
|
if (locon->NAME==locon_aux->NAME) break;
|
||||||
|
}
|
||||||
|
if (!locon_aux) {
|
||||||
|
fprintf(stderr,"change_instance: locon '%s' not found\n",
|
||||||
|
locon->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
losig_aux=locon_aux->SIG;
|
||||||
|
/*search real connection*/
|
||||||
|
for (locon_aux=lofig_aux->LOINS->LOCON; locon_aux;
|
||||||
|
locon_aux=locon_aux->NEXT){
|
||||||
|
if (losig_aux==locon_aux->SIG) break;
|
||||||
|
}
|
||||||
|
if (!locon_aux) {
|
||||||
|
fprintf(stderr,"change_instance: locon '%s' not found in cell\n",
|
||||||
|
locon->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
locon->NAME=locon_aux->NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*capacitance and critical delay*/
|
||||||
|
loins_capacitance(loins,1); /*add it own capacity (cell has changed)*/
|
||||||
|
propagate_loins_delay(loins);
|
||||||
|
|
||||||
|
/*verify change of loins*/
|
||||||
|
critical=critical_delay(lofig);
|
||||||
|
delay=loins_delay(loins,losig->NAMECHAIN->DATA);
|
||||||
|
if ((int)critical!=(int)best_critical || (int)delay!=(int)best_delay) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"change_instance: flatten error %f!=%f ps %f!=%f ps\n",
|
||||||
|
critical,best_critical,delay,best_delay);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /*end of change loins*/
|
||||||
|
|
||||||
|
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* improve capacitance of lofig on critical path by repowered instance */
|
||||||
|
/*critical path could be changed and can't be improved any more */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void improve_capa_critical_path(lofig_list* lofig, int optim_level)
|
||||||
|
{
|
||||||
|
ptype_list* ptype, *ptype2;
|
||||||
|
loins_list* loins;
|
||||||
|
locon_list* locon;
|
||||||
|
chain_list *lofigchain;
|
||||||
|
losig_list* losig;
|
||||||
|
ptype_list* long_path;
|
||||||
|
int change=1;
|
||||||
|
|
||||||
|
|
||||||
|
/*relaxation algorithm*/
|
||||||
|
while (change) {
|
||||||
|
change=0;
|
||||||
|
long_path=critical_path(lofig);
|
||||||
|
long_path=sort_capa(long_path);
|
||||||
|
|
||||||
|
/* on all signals of the critical path, improve capa*/
|
||||||
|
for (ptype=long_path; ptype; ptype=ptype->NEXT) {
|
||||||
|
losig=(losig_list*) ptype->DATA;
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"improve_capa_critical_path: no name on signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*seek latest driver*/
|
||||||
|
ptype2=getptype(losig->USER,LOFIGCHAIN);
|
||||||
|
if (!ptype2) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"improve_capa_critical_path: no lofigchain on losig '%s'\n",
|
||||||
|
(char*) losig->NAMECHAIN->DATA);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
loins=NULL;
|
||||||
|
for (lofigchain=ptype2->DATA; lofigchain; lofigchain=lofigchain->NEXT){
|
||||||
|
locon= (locon_list*) lofigchain->DATA;
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' isn't accepted\n",
|
||||||
|
locon->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (locon->TYPE==EXTERNAL || locon->DIRECTION==IN) continue;
|
||||||
|
loins=locon->ROOT;
|
||||||
|
if (loins_delay(loins,losig->NAMECHAIN->DATA)>ptype->TYPE) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*instance has changed, re-evaluate critical path*/
|
||||||
|
if (loins && change_instance(loins, losig, lofig, optim_level)) {
|
||||||
|
change=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freeptype(long_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*improve big RC of circuit */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void improve_RC_circuit(lofig_list* lofig, int optim_level)
|
||||||
|
{
|
||||||
|
loins_list* loins;
|
||||||
|
locon_list* locon;
|
||||||
|
losig_list* losig;
|
||||||
|
|
||||||
|
for (loins=lofig->LOINS; loins; loins=loins->NEXT) {
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
|
||||||
|
locon->NAME,loins->INSNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (isvdd(locon->NAME) || isvss(locon->NAME)) continue;
|
||||||
|
if (locon->DIRECTION!=IN) break;
|
||||||
|
}
|
||||||
|
if (!locon) {
|
||||||
|
fprintf(stderr,"improve_RC_circuit: no output found for '%s'\n",
|
||||||
|
loins->FIGNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
losig=locon->SIG;
|
||||||
|
change_instance(loins, losig, lofig, optim_level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return 1 if we have added a buffer */
|
||||||
|
/***************************************************************************/
|
||||||
|
static int insert_buffer(losig_list* losig, lofig_list* lofig, int optim_level, long index)
|
||||||
|
{
|
||||||
|
double capa, init_capa;
|
||||||
|
cell_list* buffer;
|
||||||
|
chain_list* namechain, *sigchain=NULL;
|
||||||
|
char* signame;
|
||||||
|
lofig_list* model;
|
||||||
|
losig_list* losig_buf;
|
||||||
|
loins_list* loins_buf;
|
||||||
|
locon_list* locon;
|
||||||
|
losig_list* losig_vdd=NULL, *losig_vss=NULL, *losig_aux;
|
||||||
|
ptype_list* ptype, *buffer_ptype;
|
||||||
|
double delay, best_delay, init_delay;
|
||||||
|
loins_list* loins;
|
||||||
|
chain_list* lofigchain,*newlofigchain=NULL;
|
||||||
|
int buffer_is_better=0, change=1; /*flags*/
|
||||||
|
chain_list* pred;
|
||||||
|
chain_list* temp;
|
||||||
|
|
||||||
|
|
||||||
|
buffer=getCellbuffer();
|
||||||
|
/*no buffer in library*/
|
||||||
|
if (!buffer) return 0;
|
||||||
|
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"insert_buffer: no name on signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
best_delay=critical_delay(lofig);
|
||||||
|
init_capa=getcapacitance(losig->NAMECHAIN->DATA);
|
||||||
|
|
||||||
|
/*add buffer to netlist*/
|
||||||
|
signame=getautoname(losig->NAMECHAIN->DATA);
|
||||||
|
namechain=addchain(NULL,signame);
|
||||||
|
losig_buf=addlosig(lofig,index,namechain,INTERNAL);
|
||||||
|
putcapacitance(signame,0);
|
||||||
|
putdelay(signame,0);
|
||||||
|
model=getlofig(buffer->BEFIG->NAME,'A');
|
||||||
|
|
||||||
|
/*search vdd and vss*/
|
||||||
|
for (locon=lofig->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (isvdd(locon->NAME)) losig_vdd=locon->SIG;
|
||||||
|
if (isvss(locon->NAME)) losig_vss=locon->SIG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*build list of signal*/
|
||||||
|
for (locon=model->LOCON;locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
|
||||||
|
locon->NAME,model->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (isvdd(locon->NAME)) losig_aux=losig_vdd;
|
||||||
|
else if (isvss(locon->NAME)) losig_aux=losig_vss;
|
||||||
|
else if (locon->DIRECTION==OUT) losig_aux=losig_buf;
|
||||||
|
else if (locon->DIRECTION==IN) losig_aux=losig;
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"insert_buffer: buffer port '%s' unknown\n",locon->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
sigchain=addchain(sigchain,losig_aux);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sigchain=reverse(sigchain);
|
||||||
|
loins_buf=addloins(lofig,signame,model,sigchain);
|
||||||
|
freechain(sigchain);
|
||||||
|
/*to check changes*/
|
||||||
|
init_delay=getdelay(losig->NAMECHAIN->DATA);
|
||||||
|
init_capa=getcapacitance(losig->NAMECHAIN->DATA);
|
||||||
|
loins_capacitance(loins_buf,1/*add capa*/);
|
||||||
|
|
||||||
|
/*lofigchain*/
|
||||||
|
for (locon=loins_buf->LOCON;locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
|
||||||
|
locon->NAME,loins_buf->INSNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (isvdd(locon->NAME)) losig_aux=losig_vdd;
|
||||||
|
else if (isvss(locon->NAME)) losig_aux=losig_vss;
|
||||||
|
else if (locon->DIRECTION==OUT) losig_aux=losig_buf;
|
||||||
|
else if (locon->DIRECTION==IN) losig_aux=losig;
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"insert_buffer: buffer port '%s' unknown\n",locon->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
ptype=getptype(losig_aux->USER,LOFIGCHAIN);
|
||||||
|
if (!ptype) losig_aux->USER=addptype(losig_aux->USER,LOFIGCHAIN,addchain(NULL,locon));
|
||||||
|
else ptype->DATA=addchain(ptype->DATA,locon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*move all instance after buffer*/
|
||||||
|
ptype=getptype(losig->USER,LOFIGCHAIN);
|
||||||
|
buffer_ptype=getptype(losig_buf->USER,LOFIGCHAIN);
|
||||||
|
if (!ptype || !buffer_ptype) {
|
||||||
|
fprintf(stderr,"insert_buffer: LOFIGCHAIN not found\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (lofigchain=((chain_list*)ptype->DATA)->NEXT/*first is entry of buffer*/;
|
||||||
|
lofigchain; lofigchain=lofigchain->NEXT) {
|
||||||
|
locon=(locon_list*) lofigchain->DATA;
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' isn't accepted\n",
|
||||||
|
locon->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*do not move drivers and port of circuit*/
|
||||||
|
if (locon->TYPE==EXTERNAL || locon->DIRECTION!=IN) {
|
||||||
|
newlofigchain=addchain(newlofigchain,locon);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
loins=locon->ROOT;
|
||||||
|
/*change capacitance*/
|
||||||
|
loins_capacitance(loins,0/*remove capa*/);
|
||||||
|
/*change netlist*/
|
||||||
|
locon->SIG=losig_buf;
|
||||||
|
buffer_ptype->DATA=addchain(buffer_ptype->DATA,locon);
|
||||||
|
loins_capacitance(loins,1/*add capa*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*put back drivers*/
|
||||||
|
freechain(((chain_list*)ptype->DATA)->NEXT/*first is entry of buffer*/);
|
||||||
|
((chain_list*)ptype->DATA)->NEXT=newlofigchain;
|
||||||
|
|
||||||
|
/*eval all changes*/
|
||||||
|
propagate_loins_delay(loins_buf);
|
||||||
|
|
||||||
|
/*relaxation algorithm*/
|
||||||
|
while (change) {
|
||||||
|
change=0;
|
||||||
|
pred=NULL;
|
||||||
|
buffer_ptype=getptype(losig_buf->USER,LOFIGCHAIN);
|
||||||
|
ptype=getptype(losig->USER,LOFIGCHAIN);
|
||||||
|
if (!buffer_ptype || !buffer_ptype->DATA) {
|
||||||
|
fprintf(stderr,"insert_buffer: LOFIGCHAIN is empty\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*put critical path before buffer*/
|
||||||
|
for (lofigchain=buffer_ptype->DATA; lofigchain->NEXT/*last is buffer output*/;
|
||||||
|
lofigchain=lofigchain->NEXT) {
|
||||||
|
locon=lofigchain->DATA;
|
||||||
|
loins=locon->ROOT;
|
||||||
|
|
||||||
|
/*change capacitance*/
|
||||||
|
loins_capacitance(loins,0/*remove capa*/);
|
||||||
|
/*change netlist*/
|
||||||
|
locon->SIG=losig;
|
||||||
|
ptype->DATA=addchain(ptype->DATA,locon);
|
||||||
|
loins_capacitance(loins,1/*add capa*/);
|
||||||
|
|
||||||
|
/*put over*/
|
||||||
|
if (pred) pred->NEXT=lofigchain->NEXT;
|
||||||
|
else buffer_ptype->DATA=lofigchain->NEXT;
|
||||||
|
|
||||||
|
/*eval all changes*/
|
||||||
|
propagate_loins_delay(loins);
|
||||||
|
propagate_loins_delay(loins_buf);
|
||||||
|
delay=critical_delay(lofig);
|
||||||
|
|
||||||
|
if (delay<best_delay) {
|
||||||
|
/*finish change*/
|
||||||
|
best_delay=delay;
|
||||||
|
change=1; /*flag of change*/
|
||||||
|
buffer_is_better=1;
|
||||||
|
lofigchain->NEXT=NULL;
|
||||||
|
freechain(lofigchain);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*remove change*/
|
||||||
|
if (pred) pred->NEXT=lofigchain;
|
||||||
|
else buffer_ptype->DATA=lofigchain;
|
||||||
|
|
||||||
|
/*unchange capacitance*/
|
||||||
|
loins_capacitance(loins,0/*remove capa*/);
|
||||||
|
/*unchange netlist*/
|
||||||
|
locon->SIG=losig_buf;
|
||||||
|
temp=ptype->DATA;
|
||||||
|
ptype->DATA=temp->NEXT;
|
||||||
|
temp->NEXT=NULL;
|
||||||
|
freechain(temp);
|
||||||
|
loins_capacitance(loins,1/*add capa*/);
|
||||||
|
/*avoid change*/
|
||||||
|
propagate_loins_delay(loins_buf);
|
||||||
|
propagate_loins_delay(loins);
|
||||||
|
|
||||||
|
/*for next loop*/
|
||||||
|
pred=lofigchain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}/*end of while*/
|
||||||
|
|
||||||
|
if (buffer_is_better) {
|
||||||
|
/*chose the best buffer*/
|
||||||
|
change_instance(loins_buf, losig_buf, lofig, optim_level);
|
||||||
|
}
|
||||||
|
else { /*if insert buffer is worst than before, remove it*/
|
||||||
|
/*remove all references of buffer in lofigchain*/
|
||||||
|
for (locon=loins_buf->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
losig_aux=locon->SIG;
|
||||||
|
ptype=getptype(losig_aux->USER,LOFIGCHAIN);
|
||||||
|
if (!ptype) break;
|
||||||
|
pred=NULL;
|
||||||
|
for (lofigchain=ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) {
|
||||||
|
if (lofigchain->DATA==locon) {
|
||||||
|
if (pred) pred->NEXT=lofigchain->NEXT;
|
||||||
|
else ptype->DATA=lofigchain->NEXT;
|
||||||
|
lofigchain->NEXT=NULL;
|
||||||
|
freechain(lofigchain);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pred=lofigchain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_ptype=getptype(losig_buf->USER,LOFIGCHAIN);
|
||||||
|
ptype=getptype(losig->USER,LOFIGCHAIN);
|
||||||
|
if (buffer_ptype) {
|
||||||
|
for (lofigchain=buffer_ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) {
|
||||||
|
locon=lofigchain->DATA;
|
||||||
|
loins=locon->ROOT;
|
||||||
|
/*change capacitance*/
|
||||||
|
loins_capacitance(loins,0/*remove capa*/);
|
||||||
|
/*change netlist*/
|
||||||
|
locon->SIG=losig;
|
||||||
|
ptype->DATA=addchain(ptype->DATA,locon);
|
||||||
|
loins_capacitance(loins,1/*add capa*/);
|
||||||
|
propagate_loins_delay(loins);
|
||||||
|
}
|
||||||
|
|
||||||
|
freechain(buffer_ptype->DATA);
|
||||||
|
buffer_ptype->DATA=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
loins_capacitance(loins_buf,0/*remove capa*/);
|
||||||
|
dellosig(lofig,index);
|
||||||
|
delloins(lofig,loins_buf->INSNAME);
|
||||||
|
propagate_losig_delay(losig);
|
||||||
|
|
||||||
|
/*verify no change on timing*/
|
||||||
|
delay=critical_delay(lofig);
|
||||||
|
capa=getcapacitance(losig->NAMECHAIN->DATA);
|
||||||
|
if ((int)capa!=(int)init_capa || (int)delay!=(int)best_delay
|
||||||
|
|| (int)init_delay!=(int)getdelay(losig->NAMECHAIN->DATA)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"insert_buffer: compute error %e!=%e fF %f!=%f ps %f!=%f ps\n",
|
||||||
|
capa,init_capa,delay,best_delay, init_delay, getdelay(losig->NAMECHAIN->DATA));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer_is_better;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* improve capacitance of lofig on critical path by adding buffer */
|
||||||
|
/*critical path could be changed and can't be improved any more */
|
||||||
|
/*return the number of buffers inserted */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern int insert_buffer_critical_path(lofig_list* lofig, int optim_level)
|
||||||
|
{
|
||||||
|
ptype_list* ptype;
|
||||||
|
losig_list* losig;
|
||||||
|
ptype_list* long_path;
|
||||||
|
long count=0;
|
||||||
|
long index=0;
|
||||||
|
int change=1;
|
||||||
|
|
||||||
|
/*search new index*/
|
||||||
|
for (losig = lofig->LOSIG; losig; losig = losig->NEXT) {
|
||||||
|
if (index < losig->INDEX) index = losig->INDEX;
|
||||||
|
}
|
||||||
|
if (index!=0) index++;
|
||||||
|
|
||||||
|
|
||||||
|
/*relaxation algorithm*/
|
||||||
|
while (change) {
|
||||||
|
change=0;
|
||||||
|
/*too dangerous to put some buffer on clock!!!*/
|
||||||
|
long_path=critical_path_without_clock(lofig);
|
||||||
|
long_path=sort_capa(long_path);
|
||||||
|
|
||||||
|
/* on all signals of the critical path, improve capa*/
|
||||||
|
for (ptype=long_path; ptype; ptype=ptype->NEXT) {
|
||||||
|
losig=(losig_list*) ptype->DATA;
|
||||||
|
if (insert_buffer(losig, lofig, optim_level, index)) {
|
||||||
|
count++;
|
||||||
|
index++;
|
||||||
|
change=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freeptype(long_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - delay netlits
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OPTIM_CAPA_H
|
||||||
|
#define OPTIM_CAPA_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* improve capacitance of lofig on critical path by repowered instance */
|
||||||
|
/*critical path could be changed and can't be improved any more */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void improve_capa_critical_path __P ((lofig_list* lofig, int optim_level));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*improve big RC of circuit */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void improve_RC_circuit __P ((lofig_list* lofig, int optim_level));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* improve capacitance of lofig on critical path by adding buffer */
|
||||||
|
/*critical path could be changed and can't be improved any more */
|
||||||
|
/*return the number of buffers inserted */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern int insert_buffer_critical_path __P ((lofig_list* lofig, int optim_level));
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - statistics
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include "lon_lib_utils.h"
|
||||||
|
#include "lon_signal_netlist.h"
|
||||||
|
#include "lon_optim_stats.h"
|
||||||
|
|
||||||
|
/*worst RC*/
|
||||||
|
static long AREA;
|
||||||
|
static long NUM_INS;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* return the area of lofig */
|
||||||
|
/*count_instance() should be caught first */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern long getarea(lofig_list* lofig)
|
||||||
|
{
|
||||||
|
return AREA;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* return the area of lofig */
|
||||||
|
/*percent_instance() should be caught first */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern long getnum_ins(lofig_list* lofig)
|
||||||
|
{
|
||||||
|
return NUM_INS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* return the number of loins used in lofig */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern ptype_list* count_instance(lofig_list* lofig)
|
||||||
|
{
|
||||||
|
ptype_list *ptype, *temp=NULL, *inst=NULL, *low, *pred, *pred_low;
|
||||||
|
loins_list* loins;
|
||||||
|
|
||||||
|
if (!lofig) {
|
||||||
|
fprintf(stderr,"count_instance: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
NUM_INS=0;
|
||||||
|
|
||||||
|
for (loins=lofig->LOINS; loins; loins=loins->NEXT) {
|
||||||
|
for (ptype=temp; ptype; ptype=ptype->NEXT) {
|
||||||
|
if ((char*)ptype->DATA==loins->FIGNAME) break;
|
||||||
|
}
|
||||||
|
if (ptype) ptype->TYPE++;
|
||||||
|
else temp=addptype(temp,1,loins->FIGNAME);
|
||||||
|
NUM_INS++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*sort*/
|
||||||
|
while (temp) {
|
||||||
|
low=temp;
|
||||||
|
pred_low=NULL;
|
||||||
|
pred=temp;
|
||||||
|
|
||||||
|
/*search the lowest elem*/
|
||||||
|
for (ptype=temp->NEXT; ptype; ptype=ptype->NEXT) {
|
||||||
|
if (ptype->TYPE<low->TYPE) {
|
||||||
|
pred_low=pred;
|
||||||
|
low=ptype;
|
||||||
|
}
|
||||||
|
pred=ptype;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*extract it from netlist*/
|
||||||
|
if (!pred_low) temp=low->NEXT;
|
||||||
|
else pred_low->NEXT=low->NEXT;
|
||||||
|
|
||||||
|
low->NEXT=inst;
|
||||||
|
inst=low;
|
||||||
|
}
|
||||||
|
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/*give the percentage of area of each modelcontained in model_list */
|
||||||
|
/*count_instance() should be caught first */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern ptype_list* percent_instance(ptype_list* model_list)
|
||||||
|
{
|
||||||
|
ptype_list *ptype, *inst=NULL;
|
||||||
|
cell_list* cell;
|
||||||
|
|
||||||
|
AREA=0;
|
||||||
|
|
||||||
|
if (!model_list) return NULL;
|
||||||
|
|
||||||
|
/*eval area occupied by each model*/
|
||||||
|
for (ptype=model_list; ptype; ptype=ptype->NEXT) {
|
||||||
|
cell=getCell((char*)ptype->DATA);
|
||||||
|
if (!cell) {
|
||||||
|
fprintf(stderr,"Library Error: cell '%s' not found\n",cell->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
inst=addptype(inst,cell->AREA*ptype->TYPE,ptype->DATA);
|
||||||
|
AREA+=cell->AREA*ptype->TYPE;
|
||||||
|
}
|
||||||
|
inst=(ptype_list*) reverse((chain_list*) inst);
|
||||||
|
|
||||||
|
/*in percent*/
|
||||||
|
for (ptype=inst; ptype; ptype=ptype->NEXT) {
|
||||||
|
ptype->TYPE=(long) ((double)ptype->TYPE*100)/((double)AREA);
|
||||||
|
}
|
||||||
|
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*return the RC maximum of lofig */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double getmaxRC(lofig_list* lofig)
|
||||||
|
{
|
||||||
|
double t, RC=0;
|
||||||
|
loins_list* loins;
|
||||||
|
locon_list* locon;
|
||||||
|
losig_list* losig;
|
||||||
|
|
||||||
|
for (loins=lofig->LOINS; loins; loins=loins->NEXT) {
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (isvdd(locon->NAME) || isvss(locon->NAME)
|
||||||
|
|| locon->DIRECTION==IN) continue;
|
||||||
|
losig=locon->SIG;
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"getmaxRC: no name on signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
t=loins_max_RC(loins,losig->NAMECHAIN->DATA);
|
||||||
|
if (t>RC) RC=t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - statistics
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OPTIM_STATS_H
|
||||||
|
#define OPTIM_STATS_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*return the RC maximum of lofig */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double getmaxRC __P ((lofig_list* lofig));
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* return the number of loins used in lofig */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern ptype_list* count_instance __P ((lofig_list* lofig));
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/*give the percentage of area of each modelcontained in model_list */
|
||||||
|
/*count_instance() should be caught first */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern ptype_list* percent_instance __P ((ptype_list* model_list));
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* return the area of lofig */
|
||||||
|
/*percent_instance() should be caught first */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern long getnum_ins __P ((lofig_list* lofig));
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* return the area of lofig */
|
||||||
|
/*count_instance() should be caught first */
|
||||||
|
/****************************************************************************/
|
||||||
|
extern long getarea __P ((lofig_list* lofig));
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,236 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - critical path
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include <aut.h>
|
||||||
|
#include "lon_lax_param.h"
|
||||||
|
#include "lon_lib_utils.h"
|
||||||
|
#include "lon_signal_utils.h"
|
||||||
|
#include "lon_signal_name.h"
|
||||||
|
#include "lon_signal_netlist.h"
|
||||||
|
#include "lon_signal_critical.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*return the signal with the highest delay */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern losig_list* critical_output(lofig_list* lofig)
|
||||||
|
{
|
||||||
|
double delay, max_delay=-1;
|
||||||
|
losig_list* output=NULL, *losig;
|
||||||
|
char* signame;
|
||||||
|
|
||||||
|
for (losig=lofig->LOSIG; losig; losig=losig->NEXT) {
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"critical_output: no losig name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
signame=losig->NAMECHAIN->DATA;
|
||||||
|
if (losig->TYPE==EXTERNAL) delay=getdelay(output_name(signame));
|
||||||
|
else delay=getdelay(signame);
|
||||||
|
if (delay>max_delay) {
|
||||||
|
max_delay=delay;
|
||||||
|
output=losig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* cost function for lofig */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double critical_delay(lofig_list* lofig)
|
||||||
|
{
|
||||||
|
losig_list* losig;
|
||||||
|
char* signame;
|
||||||
|
|
||||||
|
losig=critical_output(lofig);
|
||||||
|
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"critical_delay: no losig name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
signame=losig->NAMECHAIN->DATA;
|
||||||
|
|
||||||
|
if (losig->TYPE==EXTERNAL) return getdelay(output_name(signame));
|
||||||
|
return getdelay(signame);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* return the list of losig which are belonging to path */
|
||||||
|
/* if ck_include is set to one, include clock of register in path */
|
||||||
|
/****************************************************************************/
|
||||||
|
static ptype_list* search_long_path(losig_list* losig, int ck_include)
|
||||||
|
{
|
||||||
|
loins_list* best_loins=NULL;
|
||||||
|
locon_list* locon;
|
||||||
|
losig_list *best_losig=NULL;
|
||||||
|
loins_list* loins;
|
||||||
|
befig_list* befig;
|
||||||
|
char* signame, *ck=NULL;
|
||||||
|
int reg=0; /*flag for flip-flop*/
|
||||||
|
chain_list* lofigchain;
|
||||||
|
ptype_list* ptype, *ret;
|
||||||
|
double max_delay=-1, delay;
|
||||||
|
cell_list* cell;
|
||||||
|
|
||||||
|
if (!losig) {
|
||||||
|
fprintf(stderr,"search_long_path: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"search_long_path: no losig name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
signame=(char*) losig->NAMECHAIN->DATA;
|
||||||
|
|
||||||
|
/*search drivers*/
|
||||||
|
ptype=getptype(losig->USER,LOFIGCHAIN);
|
||||||
|
if (!ptype || !ptype->DATA) {
|
||||||
|
fprintf(stderr,"search_long_path: no lofigchain found\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (lofigchain=(chain_list*) ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) {
|
||||||
|
locon=(locon_list*) lofigchain->DATA;
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' isn't accepted\n",
|
||||||
|
locon->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*only outputs*/
|
||||||
|
if (isvss(locon->NAME) || isvdd(locon->NAME)
|
||||||
|
|| locon->DIRECTION==IN || locon->TYPE==EXTERNAL) continue;
|
||||||
|
loins=locon->ROOT;
|
||||||
|
delay=loins_delay(loins,signame);
|
||||||
|
if (delay>max_delay) {
|
||||||
|
best_loins=loins;
|
||||||
|
max_delay=delay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
loins=best_loins;
|
||||||
|
ret=addptype(NULL, (long) max_delay>=0?max_delay:getdelay(signame), losig);
|
||||||
|
if (!loins) return ret;
|
||||||
|
|
||||||
|
/*stop at flip-flop*/
|
||||||
|
cell=getCell(loins->FIGNAME);
|
||||||
|
if (!cell) {
|
||||||
|
fprintf(stderr,"library error: no cell '%s.vbe' found\n",
|
||||||
|
loins->FIGNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
befig=cell->BEFIG;
|
||||||
|
if (befig->BEREG) {
|
||||||
|
ptype=getptype(befig->BEREG->BIABL->USER,ABL_STABLE);
|
||||||
|
if (ptype) {
|
||||||
|
/*do not include clock in path*/
|
||||||
|
if (!ck_include) return ret;
|
||||||
|
reg=1;
|
||||||
|
ck=ptype->DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
max_delay=-1;
|
||||||
|
/*seek the latest input in cell*/
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
|
||||||
|
locon->NAME,loins->FIGNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*only inputs*/
|
||||||
|
if (locon->DIRECTION==OUT || locon->DIRECTION==TRISTATE
|
||||||
|
|| isvss(locon->NAME) || isvdd(locon->NAME)) continue;
|
||||||
|
/* if flip-flop, accept only clock */
|
||||||
|
if (reg && ck!=locon->NAME) continue;
|
||||||
|
losig=locon->SIG;
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"search_long_path: no name on signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
signame=(char*) losig->NAMECHAIN->DATA;
|
||||||
|
delay=getdelay(signame);
|
||||||
|
if (delay>max_delay) {
|
||||||
|
best_losig=losig;
|
||||||
|
max_delay=delay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
losig=best_losig;
|
||||||
|
|
||||||
|
|
||||||
|
/*no input found -> constant*/
|
||||||
|
if (!losig) return ret;
|
||||||
|
|
||||||
|
ret->NEXT=search_long_path(losig,ck_include);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*return the list of losig with delays which are composing critical path */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern ptype_list* critical_path(lofig_list* lofig)
|
||||||
|
{
|
||||||
|
losig_list* losig;
|
||||||
|
|
||||||
|
losig=critical_output(lofig);
|
||||||
|
/*lofig is empty*/
|
||||||
|
if (!losig) return NULL;
|
||||||
|
return (ptype_list*) reverse( (chain_list*) search_long_path(losig,1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*return the list of losig with delays which are composing critical path */
|
||||||
|
/*path do not continue on clock if a flip-flop is met */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern ptype_list* critical_path_without_clock(lofig_list* lofig)
|
||||||
|
{
|
||||||
|
losig_list* losig;
|
||||||
|
|
||||||
|
losig=critical_output(lofig);
|
||||||
|
/*lofig is empty*/
|
||||||
|
if (!losig) return NULL;
|
||||||
|
return (ptype_list*) reverse( (chain_list*) search_long_path(losig,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - critical path
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SIGNAL_CRITICAL_H
|
||||||
|
#define SIGNAL_CRITICAL_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*return the signal with the highest delay */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern losig_list* critical_output __P ((lofig_list* lofig));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* cost function for lofig */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double critical_delay __P ((lofig_list* lofig));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*return the list of losig with delays which are composing critical path */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern ptype_list* critical_path __P ((lofig_list* lofig));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*return the list of losig with delays which are composing critical path */
|
||||||
|
/*path do not continue on clock if a flip-flop is met */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern ptype_list* critical_path_without_clock __P ((lofig_list* lofig));
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - names of input
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include <aut.h>
|
||||||
|
#include "lon_signal_name.h"
|
||||||
|
|
||||||
|
/*to distinguish output of circuit*/
|
||||||
|
#define MBK_OUT namealloc("MBK_OUT")
|
||||||
|
/*other name of same instance*/
|
||||||
|
#define MBK_BUF namealloc("MBK_BUF")
|
||||||
|
#define BLOCK 1024
|
||||||
|
|
||||||
|
/*table of used name*/
|
||||||
|
static authtable* HTABLE; /*VALUE the occurrence of name*/
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* free index referencing */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void free_nameindex()
|
||||||
|
{
|
||||||
|
if (HTABLE) destroyauthtable(HTABLE);
|
||||||
|
HTABLE=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return name concatenated with an index and seperated by '_' */
|
||||||
|
/* this index is : how many times I have sent this name to getnameindex() */
|
||||||
|
/* unicity is guaranteed until you run Put_index_to_zero() below */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern char* getnameindex(char* name)
|
||||||
|
{
|
||||||
|
char memo_char;
|
||||||
|
char *radical;
|
||||||
|
int index;
|
||||||
|
authelem* elem;
|
||||||
|
|
||||||
|
name=namealloc(name);
|
||||||
|
radical=vectorradical(name);
|
||||||
|
index=vectorindex(name);
|
||||||
|
|
||||||
|
if (!HTABLE) HTABLE=createauthtable(BLOCK);
|
||||||
|
elem=searchauthelem(HTABLE,name);
|
||||||
|
|
||||||
|
if (!elem) {
|
||||||
|
addauthelem(HTABLE,name,1);
|
||||||
|
return name; /*unchanged*/
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*add an occurence*/
|
||||||
|
elem->VALUE++;
|
||||||
|
memo_char=SEPAR; /*external value from MBK environment*/
|
||||||
|
SEPAR='_';
|
||||||
|
name=nameindex(radical,elem->VALUE); /*take value SEPAR for separator*/
|
||||||
|
SEPAR=' ';
|
||||||
|
if (index!=-1) name=nameindex(name,index); /*rebuild vector*/
|
||||||
|
SEPAR=memo_char; /*not to change global environment*/
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* build a generic name with an incremented index */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern char* getautoname(char* name)
|
||||||
|
{
|
||||||
|
char memo_char;
|
||||||
|
|
||||||
|
name=namealloc(name);
|
||||||
|
|
||||||
|
memo_char=SEPAR; /*external value from MBK environment*/
|
||||||
|
SEPAR='_';
|
||||||
|
name=concatname(MBK_BUF,name);
|
||||||
|
SEPAR=memo_char;
|
||||||
|
|
||||||
|
return getnameindex(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*return a new name to distinguish output value from input when inout */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern char* output_name(char* name)
|
||||||
|
{
|
||||||
|
char memo;
|
||||||
|
|
||||||
|
memo=SEPAR;
|
||||||
|
SEPAR='_';
|
||||||
|
|
||||||
|
name=concatname(MBK_OUT,name);
|
||||||
|
|
||||||
|
SEPAR=memo;
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - delay netlits
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SIGNAL_NAME_H
|
||||||
|
#define SIGNAL_NAME_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* free index referencing */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void free_nameindex __P (());
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*return a new name to distinguish output value from input when inout */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern char* output_name __P ((char* name));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return name concatenated with an index and seperated by '_' */
|
||||||
|
/* this index is : how many times I have sent this name to getnameindex() */
|
||||||
|
/* unicity is guaranteed until you run Put_index_to_zero() below */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern char* getnameindex __P ((char* name));
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* build a generic name with an incremented index */
|
||||||
|
/******************************************************************************/
|
||||||
|
extern char* getautoname __P ((char* name));
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,531 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - special netlist for timing dependancies
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include <aut.h>
|
||||||
|
#include "lon_lax_param.h"
|
||||||
|
#include "lon_lib_utils.h"
|
||||||
|
#include "lon_signal_utils.h"
|
||||||
|
#include "lon_signal_name.h"
|
||||||
|
#include "lon_signal_netlist.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* increment(if 1) or decrement(if 0) the capacitance on signals branched */
|
||||||
|
/* to loins from the values of its ports */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void loins_capacitance(loins_list* loins, int increment)
|
||||||
|
{
|
||||||
|
port_list *port;
|
||||||
|
cell_list* cell;
|
||||||
|
locon_list* locon;
|
||||||
|
losig_list* losig;
|
||||||
|
char* signame;
|
||||||
|
|
||||||
|
cell=getCell(loins->FIGNAME);
|
||||||
|
if (!cell) {
|
||||||
|
fprintf(stderr,"library error: no model '%s.vbe' found\n",
|
||||||
|
loins->FIGNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
|
||||||
|
locon->NAME,loins->INSNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*seek port which match with netlist*/
|
||||||
|
for (port=cell->PORT; port; port=port->NEXT) {
|
||||||
|
if (port->NAME==locon->NAME) break;
|
||||||
|
}
|
||||||
|
if (!port) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"loins_capacitance: connector discrepancy between '%s' and '%s'\n",
|
||||||
|
cell->NAME,loins->FIGNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
losig=locon->SIG;
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"loins_capacitance: no losig name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
signame=losig->NAMECHAIN->DATA;
|
||||||
|
if (!isvdd(locon->NAME) && !isvss(locon->NAME)
|
||||||
|
&& (locon->DIRECTION==IN || locon->DIRECTION==INOUT
|
||||||
|
|| locon->DIRECTION==TRANSCV))
|
||||||
|
inccapacitance(signame, increment!=0 ? port->C : -port->C );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the Time of a loins */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double loins_max_T(loins_list* loins)
|
||||||
|
{
|
||||||
|
cell_list* cell;
|
||||||
|
char* ck=NULL;
|
||||||
|
int flip_flop=0;
|
||||||
|
double delay, max_delay=-1;
|
||||||
|
ptype_list* ptype;
|
||||||
|
port_list* port;
|
||||||
|
locon_list* locon;
|
||||||
|
char* input;
|
||||||
|
|
||||||
|
if (!loins) {
|
||||||
|
fprintf(stderr,"loins_max_T: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*cell properties*/
|
||||||
|
cell=getCell(loins->FIGNAME);
|
||||||
|
if (!cell) {
|
||||||
|
fprintf(stderr,"library error: no cell '%s.vbe' found\n",
|
||||||
|
loins->FIGNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*is-it a flip-flop?*/
|
||||||
|
if (cell->BEFIG->BEREG) {
|
||||||
|
ptype=getptype(cell->BEFIG->BEREG->BIABL->USER,ABL_STABLE);
|
||||||
|
if (ptype) {
|
||||||
|
flip_flop=1;
|
||||||
|
ck=(char*) ptype->DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*eval delay*/
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
|
||||||
|
locon->NAME,loins->INSNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*eval delay on input dependancy*/
|
||||||
|
if (isvdd(locon->NAME) || isvss(locon->NAME)) continue;
|
||||||
|
if (locon->DIRECTION==OUT || locon->DIRECTION==TRISTATE) continue;
|
||||||
|
/*only clock accepted for flip-flop*/
|
||||||
|
if (flip_flop && ck!=locon->NAME) continue;
|
||||||
|
|
||||||
|
/*seek port which match with netlist*/
|
||||||
|
for (port=cell->PORT; port; port=port->NEXT) {
|
||||||
|
if (port->NAME==locon->NAME) break;
|
||||||
|
}
|
||||||
|
if (!port) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"loins_max_T: connector discrepancy between '%s' and '%s'\n",
|
||||||
|
cell->NAME,loins->FIGNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!locon->SIG->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"loins_max_T: no losig name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
input=(char*) locon->SIG->NAMECHAIN->DATA;
|
||||||
|
|
||||||
|
/*finaly eval delay*/
|
||||||
|
delay=port->T;
|
||||||
|
if (delay>max_delay) max_delay=delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the RC of a loins. output is the name of the signal drived */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double loins_max_RC(loins_list* loins, char* output)
|
||||||
|
{
|
||||||
|
cell_list* cell;
|
||||||
|
char* ck=NULL;
|
||||||
|
int flip_flop=0;
|
||||||
|
double delay, max_delay=-1;
|
||||||
|
ptype_list* ptype;
|
||||||
|
port_list* port;
|
||||||
|
locon_list* locon;
|
||||||
|
char* input;
|
||||||
|
|
||||||
|
if (!loins || !output) {
|
||||||
|
fprintf(stderr,"loins_max_RC: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*cell properties*/
|
||||||
|
cell=getCell(loins->FIGNAME);
|
||||||
|
if (!cell) {
|
||||||
|
fprintf(stderr,"library error: no cell '%s.vbe' found\n",
|
||||||
|
loins->FIGNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*is-it a flip-flop?*/
|
||||||
|
if (cell->BEFIG->BEREG) {
|
||||||
|
ptype=getptype(cell->BEFIG->BEREG->BIABL->USER,ABL_STABLE);
|
||||||
|
if (ptype) {
|
||||||
|
flip_flop=1;
|
||||||
|
ck=(char*) ptype->DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*eval delay*/
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
|
||||||
|
locon->NAME,loins->INSNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*eval delay on input dependancy*/
|
||||||
|
if (isvdd(locon->NAME) || isvss(locon->NAME)) continue;
|
||||||
|
if (locon->DIRECTION==OUT || locon->DIRECTION==TRISTATE) continue;
|
||||||
|
/*only clock accepted for flip-flop*/
|
||||||
|
if (flip_flop && ck!=locon->NAME) continue;
|
||||||
|
|
||||||
|
/*seek port which match with netlist*/
|
||||||
|
for (port=cell->PORT; port; port=port->NEXT) {
|
||||||
|
if (port->NAME==locon->NAME) break;
|
||||||
|
}
|
||||||
|
if (!port) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"loins_max_RC: connector discrepancy between '%s' and '%s'\n",
|
||||||
|
cell->NAME,loins->FIGNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!locon->SIG->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"loins_max_RC: no losig name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
input=(char*) locon->SIG->NAMECHAIN->DATA;
|
||||||
|
|
||||||
|
/*finaly eval delay*/
|
||||||
|
delay=port->R*getcapacitance(output);
|
||||||
|
if (delay>max_delay) max_delay=delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the delay of a loins. output is the name of the signal drived */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double loins_delay(loins_list* loins, char* output)
|
||||||
|
{
|
||||||
|
cell_list* cell;
|
||||||
|
char* ck=NULL;
|
||||||
|
int flip_flop=0;
|
||||||
|
double delay, max_delay=-1;
|
||||||
|
ptype_list* ptype;
|
||||||
|
port_list* port;
|
||||||
|
locon_list* locon;
|
||||||
|
char* input;
|
||||||
|
|
||||||
|
if (!loins || !output) {
|
||||||
|
fprintf(stderr,"loins_delay: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*cell properties*/
|
||||||
|
cell=getCell(loins->FIGNAME);
|
||||||
|
if (!cell) {
|
||||||
|
fprintf(stderr,"library error: no cell '%s.vbe' found\n",
|
||||||
|
loins->FIGNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*is-it a flip-flop?*/
|
||||||
|
if (cell->BEFIG->BEREG) {
|
||||||
|
ptype=getptype(cell->BEFIG->BEREG->BIABL->USER,ABL_STABLE);
|
||||||
|
if (ptype) {
|
||||||
|
flip_flop=1;
|
||||||
|
ck=(char*) ptype->DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*eval delay*/
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
|
||||||
|
locon->NAME,loins->INSNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*eval delay on input dependancy*/
|
||||||
|
if (isvdd(locon->NAME) || isvss(locon->NAME)) continue;
|
||||||
|
if (locon->DIRECTION==OUT || locon->DIRECTION==TRISTATE) continue;
|
||||||
|
/*only clock accepted for flip-flop*/
|
||||||
|
if (flip_flop && ck!=locon->NAME) continue;
|
||||||
|
|
||||||
|
/*seek port which match with netlist*/
|
||||||
|
for (port=cell->PORT; port; port=port->NEXT) {
|
||||||
|
if (port->NAME==locon->NAME) break;
|
||||||
|
}
|
||||||
|
if (!port) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"loins_delay: connector discrepancy between '%s' and '%s'\n",
|
||||||
|
cell->NAME,loins->FIGNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!locon->SIG) {
|
||||||
|
fprintf(stderr,"loins_delay: no losig\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!locon->SIG->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"loins_delay: no losig name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
input=(char*) locon->SIG->NAMECHAIN->DATA;
|
||||||
|
|
||||||
|
/*finaly eval delay*/
|
||||||
|
delay=getdelay(input)+port->T+port->R*getcapacitance(output);
|
||||||
|
if (delay>max_delay) max_delay=delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the delay of a losig */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double losig_delay(losig_list* losig)
|
||||||
|
{
|
||||||
|
ptype_list* ptype;
|
||||||
|
loins_list* loins;
|
||||||
|
locon_list* locon;
|
||||||
|
double delay, max_delay=-1;
|
||||||
|
char* signame;
|
||||||
|
chain_list* lofigchain;
|
||||||
|
|
||||||
|
if (!losig) {
|
||||||
|
fprintf(stderr,"losig_delay: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"losig_delay: no losig name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
signame=losig->NAMECHAIN->DATA;
|
||||||
|
|
||||||
|
ptype=getptype(losig->USER,LOFIGCHAIN);
|
||||||
|
if (!ptype) {
|
||||||
|
fprintf(stderr,"losig_delay: no lofigchain on signal '%s'\n",
|
||||||
|
signame);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*search drivers*/
|
||||||
|
for (lofigchain=ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) {
|
||||||
|
locon= (locon_list*) lofigchain->DATA;
|
||||||
|
if (!locon) {
|
||||||
|
fprintf(stderr,"losig_delay: NULL pointer in lofigchain\n");
|
||||||
|
}
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' isn't accepted\n",
|
||||||
|
locon->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*real inputs*/
|
||||||
|
if (isvdd(locon->NAME) || isvss(locon->NAME)) continue;
|
||||||
|
if (locon->DIRECTION==IN) continue;
|
||||||
|
if (locon->TYPE!=EXTERNAL) {
|
||||||
|
loins=locon->ROOT;
|
||||||
|
delay=loins_delay(loins,signame);
|
||||||
|
if (delay>max_delay) max_delay=delay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* propagate modification of a loins for delay */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void propagate_loins_delay(loins_list *loins)
|
||||||
|
{
|
||||||
|
locon_list* locon;
|
||||||
|
|
||||||
|
/*input first*/
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
|
||||||
|
locon->NAME,loins->INSNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (locon->DIRECTION==IN || locon->DIRECTION==INOUT || locon->DIRECTION==TRANSCV)
|
||||||
|
propagate_losig_delay(locon->SIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*then output*/
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==IN) continue;
|
||||||
|
propagate_losig_delay(locon->SIG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* dispatch delay on losig modification */
|
||||||
|
/***************************************************************************/
|
||||||
|
static void loc_propagate_losig_delay(loins_list *loins)
|
||||||
|
{
|
||||||
|
locon_list* locon;
|
||||||
|
|
||||||
|
if (!loins) {
|
||||||
|
fprintf(stderr,"propagate_loins_delay: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
|
||||||
|
locon->NAME,loins->INSNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (isvdd(locon->NAME) || isvss(locon->NAME)) continue;
|
||||||
|
if (locon->DIRECTION==IN) continue;
|
||||||
|
if (!locon->SIG) {fprintf(stdout,"\n+++++%s %s\n",loins->INSNAME,loins->FIGNAME);locon->SIG->NAMECHAIN=NULL;}
|
||||||
|
propagate_losig_delay(locon->SIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* propagate modification of a losig for delay */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void propagate_losig_delay(losig_list *losig)
|
||||||
|
{
|
||||||
|
ptype_list* ptype;
|
||||||
|
loins_list* loins;
|
||||||
|
locon_list* locon;
|
||||||
|
double delay, old_delay;
|
||||||
|
char* signame;
|
||||||
|
chain_list* lofigchain;
|
||||||
|
|
||||||
|
if (!losig) {
|
||||||
|
fprintf(stderr,"propagate_losig_delay: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"propagate_losig_delay: no losig name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
signame=losig->NAMECHAIN->DATA;
|
||||||
|
delay=losig_delay(losig);
|
||||||
|
|
||||||
|
if (losig->TYPE==EXTERNAL) {
|
||||||
|
/*delay for output (memorize in special ident)*/
|
||||||
|
putdelay(output_name(signame),delay);
|
||||||
|
/*delay for input - T and R user (return 0 for signame)*/
|
||||||
|
delay=getdelaylax(signame)
|
||||||
|
+getimpedancelax(signame)*getcapacitance(signame);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*no use to propagate if unchanged*/
|
||||||
|
old_delay=getdelay(signame);
|
||||||
|
if (old_delay==delay) return;
|
||||||
|
putdelay(signame,delay);
|
||||||
|
|
||||||
|
/*propagate new delay on loins connected*/
|
||||||
|
ptype=getptype(losig->USER,LOFIGCHAIN);
|
||||||
|
if (!ptype) {
|
||||||
|
fprintf(stderr,"propagate_losig_delay: no lofigchain on signal '%s'\n",
|
||||||
|
signame);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
for (lofigchain=ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) {
|
||||||
|
locon= (locon_list*) lofigchain->DATA;
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' isn't accepted\n",
|
||||||
|
locon->NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (isvdd(locon->NAME) || isvss(locon->NAME)) continue;
|
||||||
|
if (locon->DIRECTION==OUT || locon->DIRECTION==TRISTATE) continue;
|
||||||
|
if (locon->TYPE==EXTERNAL) continue;
|
||||||
|
loins=locon->ROOT;
|
||||||
|
loc_propagate_losig_delay(loins);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* set all capacitances of signals */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void set_circuit_capacitance(lofig_list *lofig)
|
||||||
|
{
|
||||||
|
loins_list* loins;
|
||||||
|
losig_list* losig;
|
||||||
|
char* signame;
|
||||||
|
|
||||||
|
for (losig=lofig->LOSIG; losig; losig=losig->NEXT) {
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"set_circuit_capacitance: no losig name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
signame=losig->NAMECHAIN->DATA;
|
||||||
|
/*for circuit output take user propertie if defined else return 0*/
|
||||||
|
putcapacitance(signame,getcapacitancelax(signame));
|
||||||
|
putdelay(signame,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (loins=lofig->LOINS; loins; loins=loins->NEXT) {
|
||||||
|
loins_capacitance(loins,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*set all circuit delays with recursiv mode */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void set_circuit_delay(lofig_list* lofig)
|
||||||
|
{
|
||||||
|
losig_list* losig;
|
||||||
|
|
||||||
|
for (losig=lofig->LOSIG; losig; losig=losig->NEXT) {
|
||||||
|
propagate_losig_delay(losig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - delay netlits
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SIGNAL_NETLIST_H
|
||||||
|
#define SIGNAL_NETLIST_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* increment(if 1) or decrement(if 0) the capacitance on signals branched */
|
||||||
|
/* to loins from the values of its ports */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void loins_capacitance __P ((loins_list* loins, int increment));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the Time of a loins */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double loins_max_T __P ((loins_list* loins));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the RC of a loins. output is the name of the signal drived */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double loins_max_RC __P ((loins_list* loins, char* output));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the delay of a loins. output is the name of the signal drived */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double loins_delay __P ((loins_list* loins, char* output));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the delay of a losig */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double losig_delay __P ((losig_list* losig));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* propagate modification of a loins for delay */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void propagate_loins_delay __P ((loins_list *loins));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* propagate modification of a losig for delay */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void propagate_losig_delay __P ((losig_list *losig));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* set all capacitances of signals */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void set_circuit_capacitance __P ((lofig_list *lofig));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*set all circuit delays with recursiv mode */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void set_circuit_delay __P ((lofig_list* lofig));
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,274 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - signals table
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include <aut.h>
|
||||||
|
#include "lon_lax_param.h"
|
||||||
|
#include "lon_signal_utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*size of memory block*/
|
||||||
|
#define BLOCK 2048
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct signal{
|
||||||
|
struct signal* NEXT;
|
||||||
|
double T;
|
||||||
|
double C;
|
||||||
|
} signal_list;
|
||||||
|
|
||||||
|
|
||||||
|
/*table of signal delay*/
|
||||||
|
static authtable* HTABLE=NULL;
|
||||||
|
/*heap of signal structures*/
|
||||||
|
static signal_list* HEAD=NULL;
|
||||||
|
/*list of block allocated*/
|
||||||
|
static chain_list* BLOCK_LIST=NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* init memory for delay */
|
||||||
|
/***************************************************************************/
|
||||||
|
static void init_signals()
|
||||||
|
{
|
||||||
|
HTABLE= createauthtable (BLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* free memory for delay */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void free_signals()
|
||||||
|
{
|
||||||
|
chain_list* chain;
|
||||||
|
if (HTABLE) destroyauthtable(HTABLE);
|
||||||
|
HTABLE=NULL;
|
||||||
|
/*destroy block per block*/
|
||||||
|
for (chain=BLOCK_LIST; chain; chain=chain->NEXT) {
|
||||||
|
HEAD=chain->DATA;
|
||||||
|
mbkfree(HEAD);
|
||||||
|
}
|
||||||
|
if (BLOCK_LIST) freechain(BLOCK_LIST);
|
||||||
|
BLOCK_LIST=NULL;
|
||||||
|
HEAD=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return a new signal */
|
||||||
|
/***************************************************************************/
|
||||||
|
static signal_list* newsignal()
|
||||||
|
{
|
||||||
|
signal_list* new;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!HEAD) {
|
||||||
|
HEAD=mbkalloc(BLOCK*sizeof(signal_list));
|
||||||
|
BLOCK_LIST=addchain(BLOCK_LIST,HEAD);
|
||||||
|
new=HEAD;
|
||||||
|
for (i = 1; i < BLOCK; i++) {
|
||||||
|
new->NEXT = new + 1;
|
||||||
|
new++;
|
||||||
|
}
|
||||||
|
new->NEXT = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
new=HEAD;
|
||||||
|
HEAD=HEAD->NEXT;
|
||||||
|
|
||||||
|
/*fill signal*/
|
||||||
|
new->NEXT=NULL; /*not to interfer with below*/
|
||||||
|
new->C=DEFAULT_CAPACITANCE;
|
||||||
|
new->T=DEFAULT_DELAY;
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* put a signal in hash table */
|
||||||
|
/***************************************************************************/
|
||||||
|
static void putsignal(signal_list* signal, char* name)
|
||||||
|
{
|
||||||
|
if (!name || !signal) {
|
||||||
|
fprintf(stderr,"putsignal: NULL pointer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if doesn't exist hash table, init*/
|
||||||
|
if (!HTABLE) init_signals();
|
||||||
|
|
||||||
|
addauthelem(HTABLE,name,(int)signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* search a signal in hash table */
|
||||||
|
/*if doesn't exist, create the signal if create param is 1 */
|
||||||
|
/***************************************************************************/
|
||||||
|
static signal_list* getsignal(char *name, int create)
|
||||||
|
{
|
||||||
|
authelem* elem;
|
||||||
|
signal_list* signal;
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
fprintf(stderr,"getsignal: no name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if doesn't exist hash table, init*/
|
||||||
|
if (!HTABLE) init_signals();
|
||||||
|
|
||||||
|
elem=searchauthelem(HTABLE,name);
|
||||||
|
if (elem) return (signal_list*) elem->VALUE;
|
||||||
|
|
||||||
|
if (create==0) {
|
||||||
|
fprintf(stderr,"getsignal: '%s' not found in hash table\n",name);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*create new signal*/
|
||||||
|
signal=newsignal();
|
||||||
|
putsignal(signal,name);
|
||||||
|
return signal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* put a delay to a signal */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void putdelay(char* name, double delay)
|
||||||
|
{
|
||||||
|
signal_list* signal;
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
fprintf(stderr,"putdelay: no name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal=getsignal(name,1/*if doesn't exist create it*/);
|
||||||
|
signal->T=delay;
|
||||||
|
if (signal->T<0) signal->T=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the signal delay */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double getdelay(char* name)
|
||||||
|
{
|
||||||
|
signal_list* signal;
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
fprintf(stderr,"getdelay: no name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal=getsignal(name,0/*if doesn't exist then error*/);
|
||||||
|
return signal->T;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* add a delay to a signal */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void incdelay(char* name, double delay)
|
||||||
|
{
|
||||||
|
signal_list* signal;
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
fprintf(stderr,"incdelay: no name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal=getsignal(name,0);
|
||||||
|
signal->T+=delay;
|
||||||
|
if (signal->T<0) signal->T=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the signal capacitance */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double getcapacitance(char* name)
|
||||||
|
{
|
||||||
|
signal_list* signal;
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
fprintf(stderr,"getcapacitance: no name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal=getsignal(name,0/*if doesn't exist then error*/);
|
||||||
|
return signal->C;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* add a capacitance to a signal */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void inccapacitance(char* name, double capacitance)
|
||||||
|
{
|
||||||
|
signal_list* signal;
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
fprintf(stderr,"inccapacitance: no name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal=getsignal(name,0/*if doesn't exist then error*/);
|
||||||
|
signal->C+=capacitance;
|
||||||
|
if (signal->C<0) signal->C=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* put a capacitance to a signal */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void putcapacitance(char* name, double capacitance)
|
||||||
|
{
|
||||||
|
signal_list* signal;
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
fprintf(stderr,"putcapacitance: no name\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal=getsignal(name,1/*if doesn't exist create it*/);
|
||||||
|
signal->C=capacitance;
|
||||||
|
if (signal->C<0) signal->C=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : LooN - signals table
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SIGNAL_UTILS_H
|
||||||
|
#define SIGNAL_UTILS_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* free memory from image of signals in hash table */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void free_signals __P (());
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* put a delay to a signal (local hash table) */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void putdelay __P ((char* name, double delay));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the signal delay (local hash table) */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double getdelay __P ((char* name));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* add a delay to a signal */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void incdelay __P ((char* name, double delay));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* return the signal capacitance */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern double getcapacitance __P ((char* name));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* add a capacitance to a signal */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void inccapacitance __P ((char* name, double capacitance));
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* put a capacitance to a signal */
|
||||||
|
/***************************************************************************/
|
||||||
|
extern void putcapacitance __P ((char* name, double capacitance));
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,345 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License aint
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : Loon and Boog - xsch color driver
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet, Ludovic Jacomme(for xsch)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <mut.h>
|
||||||
|
#include <abl.h>
|
||||||
|
#include <mlo.h>
|
||||||
|
#include <abe.h>
|
||||||
|
#include "lon_lib_utils.h"
|
||||||
|
#include "lon_signal_utils.h"
|
||||||
|
#include "lon_signal_netlist.h"
|
||||||
|
#include "lon_signal_name.h"
|
||||||
|
#include "lon_xsch_driver.h"
|
||||||
|
|
||||||
|
#define XSCH_COLOR_MAX 32
|
||||||
|
#define XSCH_RED_COLOR 32
|
||||||
|
#define XSCH_NEUTRAL_COLOR (-1)
|
||||||
|
#define XSCH_PATH "P"
|
||||||
|
#define XSCH_CON "C"
|
||||||
|
#define XSCH_BOX "B"
|
||||||
|
#define XSCH_NET "N"
|
||||||
|
#define XSCH_SEPAR ":"
|
||||||
|
#define XSCH_END "\n"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* return the color in proportion of delay */
|
||||||
|
/*****************************************************************************/
|
||||||
|
static long gradient_color(double delay, double gradient)
|
||||||
|
{
|
||||||
|
long color;
|
||||||
|
color=(long) (delay/gradient);
|
||||||
|
|
||||||
|
if (color>XSCH_COLOR_MAX) return XSCH_COLOR_MAX;
|
||||||
|
else return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* dump into strem .xsc color format */
|
||||||
|
/**********************************************************************/
|
||||||
|
static void flush_loins(FILE* stream, char* name, long color, double delay)
|
||||||
|
{
|
||||||
|
|
||||||
|
fprintf(stream,XSCH_BOX XSCH_SEPAR "%s" XSCH_SEPAR "%ld" XSCH_SEPAR "%d ps" XSCH_END ,
|
||||||
|
name, color, (int)delay);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* dump into strem .xsc color format */
|
||||||
|
/**********************************************************************/
|
||||||
|
static void flush_path(FILE* stream, char* source, char* signame, char* dest, long color, double delay)
|
||||||
|
{
|
||||||
|
|
||||||
|
fprintf(stream, XSCH_PATH XSCH_SEPAR "%s" XSCH_SEPAR "%s" XSCH_SEPAR
|
||||||
|
"%s" XSCH_SEPAR "%ld" XSCH_SEPAR "%d ps" XSCH_END ,
|
||||||
|
source, signame, dest, color, (int)delay);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* dump into strem .xsc color format */
|
||||||
|
/**********************************************************************/
|
||||||
|
static void flush_losig(FILE* stream, char* name, long color, double delay)
|
||||||
|
{
|
||||||
|
|
||||||
|
fprintf(stream,XSCH_NET XSCH_SEPAR "%s" XSCH_SEPAR "%ld" XSCH_SEPAR "%d ps" XSCH_END ,
|
||||||
|
name, color, (int)delay);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* dump into strem .xsc color format */
|
||||||
|
/***********************************************************************/
|
||||||
|
static void flush_stream_special(FILE* stream, char* name, long color, char* mes)
|
||||||
|
{
|
||||||
|
fprintf(stream,XSCH_CON XSCH_SEPAR "%s" XSCH_SEPAR "%ld" XSCH_SEPAR "%s" XSCH_END
|
||||||
|
, name, color, mes);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* dump in xsch_file with format .xsc the weight of signals in delay */
|
||||||
|
/* if signals belong to long_path a warning color is chosen */
|
||||||
|
/*lofigchain is needed in lofig */
|
||||||
|
/**********************************************************************/
|
||||||
|
extern void save_xsch(FILE* xsch_stream, lofig_list* lofig, ptype_list* long_path, int color_mode)
|
||||||
|
{
|
||||||
|
long color;
|
||||||
|
ptype_list* ptype, *ptype2=NULL;
|
||||||
|
double delay=0, delay_out=0;
|
||||||
|
char mes[1024];
|
||||||
|
char* signame;
|
||||||
|
locon_list* locon;
|
||||||
|
losig_list* losig;
|
||||||
|
double gradient=1;
|
||||||
|
int count;
|
||||||
|
loins_list* loins;
|
||||||
|
char *source, *dest=NULL, *last_sig;
|
||||||
|
chain_list* chain, *loinschain=NULL;
|
||||||
|
chain_list* lofigchain;
|
||||||
|
losig_list* losig_aux;
|
||||||
|
|
||||||
|
/*build gradient*/
|
||||||
|
if (long_path && color_mode==XSCH_GRADIENT) {
|
||||||
|
/*get time of last entry*/
|
||||||
|
count=1;
|
||||||
|
for (ptype=long_path; ptype->NEXT; ptype=ptype->NEXT) count++;
|
||||||
|
|
||||||
|
if (!ptype->DATA) {
|
||||||
|
fprintf(stderr,"save_xsch: compute error\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
delay=ptype->TYPE;
|
||||||
|
gradient=delay/((double)XSCH_COLOR_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*color for signals*/
|
||||||
|
for (losig=lofig->LOSIG; losig; losig=losig->NEXT) {
|
||||||
|
|
||||||
|
if (!losig->NAMECHAIN || !losig->NAMECHAIN->DATA) {
|
||||||
|
fprintf(stderr,"save_xsch: no name for signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
signame=losig->NAMECHAIN->DATA;
|
||||||
|
|
||||||
|
if (isvdd(signame) || isvss(signame)) continue;
|
||||||
|
|
||||||
|
if (losig->TYPE==EXTERNAL) {
|
||||||
|
/*search external output*/
|
||||||
|
ptype=getptype(losig->USER,LOFIGCHAIN);
|
||||||
|
for (lofigchain=ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) {
|
||||||
|
locon=lofigchain->DATA;
|
||||||
|
if (locon->TYPE==EXTERNAL && locon->DIRECTION!=IN) break;
|
||||||
|
}
|
||||||
|
if (lofigchain) delay=getdelay(output_name(signame));
|
||||||
|
else delay=getdelay(signame);
|
||||||
|
}
|
||||||
|
else delay=getdelay(signame);
|
||||||
|
|
||||||
|
switch (color_mode) {
|
||||||
|
case XSCH_GRADIENT: color=gradient_color(delay,gradient); break;
|
||||||
|
case XSCH_CRITICAL_PATH: default: color=XSCH_NEUTRAL_COLOR; break;
|
||||||
|
}
|
||||||
|
flush_losig(xsch_stream, signame, color, delay);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*color for instances*/
|
||||||
|
for (loins=lofig->LOINS; loins; loins=loins->NEXT) {
|
||||||
|
/*search signal output*/
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==UNKNOWN) {
|
||||||
|
fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
|
||||||
|
locon->NAME,loins->INSNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (locon->DIRECTION==OUT || locon->DIRECTION==INOUT
|
||||||
|
|| locon->DIRECTION==TRISTATE || locon->DIRECTION==TRANSCV) break;
|
||||||
|
}
|
||||||
|
if (!locon) {
|
||||||
|
fprintf(stderr,"save_xsch: no output found for '%s'\n",loins->INSNAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
losig=locon->SIG;
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"save_xsch: no name on signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
signame=losig->NAMECHAIN->DATA;
|
||||||
|
|
||||||
|
delay=loins_delay(loins,signame);
|
||||||
|
|
||||||
|
switch (color_mode) {
|
||||||
|
case XSCH_GRADIENT: color=gradient_color(delay,gradient); break;
|
||||||
|
case XSCH_CRITICAL_PATH: default:
|
||||||
|
/*is instance in critical path?*/
|
||||||
|
for (ptype=long_path; ptype; ptype=ptype->NEXT) {
|
||||||
|
if ((char*)ptype->DATA!=signame) continue;
|
||||||
|
/*if output and input signals belong to critical path,*/
|
||||||
|
/*then instance belongs*/
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==OUT || locon->DIRECTION==TRISTATE) continue;
|
||||||
|
losig_aux=locon->SIG;
|
||||||
|
if (!losig_aux->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"save_xsch: no name on signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*is signal in critical path?*/
|
||||||
|
for (ptype2=long_path; ptype2; ptype2=ptype2->NEXT) {
|
||||||
|
if ((char*)ptype2->DATA==losig_aux->NAMECHAIN->DATA) break;
|
||||||
|
}
|
||||||
|
if (ptype2) break;
|
||||||
|
}
|
||||||
|
ptype=ptype2; /*found?*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*build critical path list*/
|
||||||
|
if (ptype) loinschain=addchain(loinschain,loins);
|
||||||
|
|
||||||
|
if (ptype) color=XSCH_RED_COLOR;
|
||||||
|
else color=XSCH_NEUTRAL_COLOR;
|
||||||
|
}
|
||||||
|
flush_loins(xsch_stream, loins->INSNAME, color, delay);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*color for connectors*/
|
||||||
|
for (locon=lofig->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
|
||||||
|
if (isvdd(locon->NAME) || isvss(locon->NAME)) continue;
|
||||||
|
|
||||||
|
switch (locon->DIRECTION) {
|
||||||
|
case IN:
|
||||||
|
delay_out=getdelay(locon->NAME);
|
||||||
|
sprintf(mes, "%d ps",(int)delay_out);
|
||||||
|
break;
|
||||||
|
case OUT: case TRISTATE:
|
||||||
|
delay_out=getdelay(output_name(locon->NAME));
|
||||||
|
sprintf(mes, "%d ps",(int)delay_out);
|
||||||
|
break;
|
||||||
|
case INOUT: case TRANSCV:
|
||||||
|
delay=getdelay(locon->NAME);
|
||||||
|
delay_out=getdelay(output_name(locon->NAME));
|
||||||
|
sprintf(mes, "%d ps on input; %d ps on output",(int)delay,(int)delay_out);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (color_mode) {
|
||||||
|
case XSCH_GRADIENT: color=gradient_color(delay_out,gradient); break;
|
||||||
|
case XSCH_CRITICAL_PATH: default:
|
||||||
|
/* seek if signal is in a long path*/
|
||||||
|
for (ptype=long_path; ptype; ptype=ptype->NEXT) {
|
||||||
|
if ((char*)ptype->DATA==locon->NAME) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptype) color=XSCH_RED_COLOR;
|
||||||
|
else color=XSCH_NEUTRAL_COLOR;
|
||||||
|
}
|
||||||
|
flush_stream_special(xsch_stream, locon->NAME, color, mes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*critical path*/
|
||||||
|
if (loinschain && long_path && color_mode==XSCH_CRITICAL_PATH) {
|
||||||
|
source=NULL;
|
||||||
|
last_sig=NULL;
|
||||||
|
for (ptype=long_path; ptype; ptype=ptype->NEXT) {
|
||||||
|
signame=ptype->DATA;
|
||||||
|
for (chain=loinschain; chain; chain=chain->NEXT) {
|
||||||
|
loins=chain->DATA;
|
||||||
|
/*search signal output*/
|
||||||
|
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
|
||||||
|
if (locon->DIRECTION==OUT || locon->DIRECTION==INOUT
|
||||||
|
|| locon->DIRECTION==TRISTATE || locon->DIRECTION==TRANSCV) {
|
||||||
|
losig=locon->SIG;
|
||||||
|
if (!losig->NAMECHAIN) {
|
||||||
|
fprintf(stderr,"save_xsch: no name on signal\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (losig->NAMECHAIN->DATA==signame) {
|
||||||
|
dest=loins->INSNAME;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (locon) break;
|
||||||
|
}
|
||||||
|
/*if no instance found it is external connector. it has the same name than signal*/
|
||||||
|
if (!locon) dest=signame;
|
||||||
|
|
||||||
|
if (source)
|
||||||
|
flush_path(xsch_stream, source, last_sig, dest, XSCH_RED_COLOR, delay);
|
||||||
|
|
||||||
|
source=dest;
|
||||||
|
last_sig=signame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*for last signal search output*/
|
||||||
|
if (losig) {
|
||||||
|
ptype=getptype(losig->USER,LOFIGCHAIN);
|
||||||
|
for (chain=ptype->DATA; chain; chain=chain->NEXT) {
|
||||||
|
locon=chain->DATA;
|
||||||
|
/*port of circuit*/
|
||||||
|
if (locon->TYPE==EXTERNAL) {dest=locon->NAME; break;}
|
||||||
|
loins=locon->ROOT;
|
||||||
|
/*register input if no error*/
|
||||||
|
if (locon->DIRECTION==IN || locon->DIRECTION==INOUT || locon->DIRECTION==TRANSCV)
|
||||||
|
{dest=loins->INSNAME; break;}
|
||||||
|
}
|
||||||
|
flush_path(xsch_stream, source, signame, dest, XSCH_RED_COLOR, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
freechain(loinschain);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Alliance CAD System
|
||||||
|
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||||
|
* Universite Pierre et Marie Curie
|
||||||
|
*
|
||||||
|
* Home page : http://www-asim.lip6.fr/alliance/
|
||||||
|
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||||
|
*
|
||||||
|
* This progam is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tool : Loon and Boog - xsch color driver
|
||||||
|
* Date : 2000
|
||||||
|
* Author : Francois Donnet, Ludovic Jacomme(for xsch)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XSCH_DRIVER_H
|
||||||
|
#define XSCH_DRIVER_H
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__ || __GNUC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define XSCH_CRITICAL_PATH 0
|
||||||
|
#define XSCH_GRADIENT 1
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/* dump in xsch_file with format .xsc the weight of signals in delay */
|
||||||
|
/* if signals belong to long_path a warning color is chosen */
|
||||||
|
/*lofigchain is needed in lofig */
|
||||||
|
/***************************************************************************************/
|
||||||
|
extern void save_xsch __P ((FILE* xsch_stream, lofig_list* lofig, ptype_list* long_path, int color_mode));
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue