premiere entree de boog

Ne compile pas encore... en attente de l'install des libs abe abv ....
This commit is contained in:
Francois Donnet 2002-03-21 13:39:58 +00:00
parent d1fc915a35
commit 49bf97be1b
76 changed files with 15479 additions and 0 deletions

View File

@ -0,0 +1,3 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = doc src

View File

@ -0,0 +1,33 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(src/bog_main.c)
BOOG_MAJOR_VERSION=1
BOOG_MINOR_VERSION=4
BOOG_VERSION=$BOOG_MAJOR_VERSION.$BOOG_MINOR_VERSION
AC_SUBST(BOOG_MAJOR_VERSION)
AC_SUBST(BOOG_MINOR_VERSION)
AC_SUBST(BOOG_VERSION)
# For automake.
VERSION=$BOOG_VERSION
PACKAGE=boog
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
])

View File

@ -0,0 +1,4 @@
## Process this file with automake to produce Makefile.in
man_MANS = boog.1
EXTRA_DIST = $(man_MANS)

View File

@ -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 : 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 BOOG 1 "Jun 29 2000" "ASIM/LIP6" "CAO\-VLSI Reference Manual"
.SH NAME
.TP
BooG \- Binding and Optimizing On Gates.
.so man1/alc_origin.1
.SH SYNOPSIS
.TP
\f4boog\fP [-hmxold] \fIinput_file\fP \fIoutput_file\fP [\fIlax_file\fP]
.br
.SH DESCRIPTION
.br
\f4boog\fP is a mapper of a behavioural description onto a predefined standard cell library as SXLIB.
It is the second step of the logic synthesis: it builds a gate network using a standard cell library.
.br
.br
\f4 Input file description\fP
.br
The logic level behavioural description (.vbe file) uses the same VHDL subset as the logic simulator \f4asimut\fP, the FSM synthesizer \f4syf\fP, the functional abstractor \f4yagle\fP and the formal prover \f4proof\fP (for further information about the subset of VHDL, see the "vbe" manual).
.br
Some constraints due to hardware mapping exist. These attributes are only supported by technology mapping onto a standard cell library as \f4sxlib\fP.
.br
For the register signal description, only one condition statement must appear. STABLE must be strictely used as a negativ motion and joined to clock setup value. Setup can be on high or low value, but it would be worthy to choose it accordingly with hardware register cell.
.br
\fI# Example\fP
label: BLOCK (NOT ck 'STABLE and ck='1')
BEGIN
reg <= GUARDED expr;
END BLOCK;
You can also put a write enable condition to your register:
label: BLOCK (NOT ck 'STABLE and ck='1' and wen='1')
BEGIN
reg <= GUARDED expr;
END BLOCK;
.fi
.ti 7
A special feature has been introduced in the VHDL subset in order to allow the don't care description for external outputs and internal registers : A bit signal can take the 'd' value.
This value is interpreted as a '0' by the logic simulator \f4asimut\fP.
Don't Cares are automatically generated by \f4syf\fP in the resulting '.vbe' file.
.br
\f4 Output file description\fP
.br
A pure standard cell netlist is produced by \f4boog\fP. This file is destinated for /fBloon/fP alliance utility to improve RC delays.
Any equipotential keeps its name from connector to connector. In trouble case, buffers are inserted to respect this VHDL constraint.
.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
.br
\f4 Mapping with a standard cell library\fP
.br
Every cell appearing in the directory defined by the environment variable MBK_TARGET_LIB may be used by \f4boog\fP since they are described as a '.vbe' file. There are some restrictions about the type of the cell used. Every cell has to have only one output.
The cell must be characterized. The timing and area informations required by \f4boog\fP are specified in the "generic" clause of the ".vbe" file.
.br
.SH OPTION
.TP 10
\f4\-h\fP
Help mode. Displays possible uses of \f4boog\fP.
.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\-o output_file\fP
Just another way to show explicitely the \f4VST\fP output file name.
.TP 10
\f4\-l lax_file\fP
Just another way to show explicitely the \f4LAX\fP parameter file name.
.TP 10
\f4\-d debug_file\fP
Generates a \f4VBE\f debug file. It comes from internal result algorithm. Users aren't concerned.
.br
.SH ENVIRONMENT VARIABLES
.br
The following environment variables have to be set before using \f4boog\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_OUT_LO\fP gives the output format of the structural description.
.SH EXAMPLE
.br
You can call \f4boog\fP as follows :
.br
.br
boog alu alu
.SH SEE ALSO
.br
boog(1), boom(1), loon(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

View File

@ -0,0 +1,33 @@
## Process this file with automake to produce Makefile.in
bin_PROGRAMS = boog
boog_LDADD = @LIBS@ \
-lAbv -lAbe -lAbt -lMlu -lMcl -lMal -lMsl -lMhl -lMel -lMvl -lMgl -lRcn -lMlo -lBdd -lAbl -lAut -lMut
boog_SOURCES = \
bog_lax_param.c bog_map_adapt.h bog_normalize_simplify.h \
bog_lax_param.h bog_map_befig.c bog_signal_adapt.c \
bog_lib_cell.c bog_map_befig.h bog_signal_adapt.h \
bog_lib_cell.h bog_map_delay.c bog_signal_delay.c \
bog_lib_complete.c bog_map_delay.h bog_signal_delay.h \
bog_lib_complete.h bog_map_pattern.c bog_signal_nameindex.c \
bog_lib_format.c bog_map_pattern.h bog_signal_nameindex.h \
bog_lib_format.h bog_map_prepare.c bog_signal_utils.c \
bog_lib_matching.c bog_map_prepare.h bog_signal_utils.h \
bog_lib_matching.h bog_normalize_ARITY.c bog_unflatten_abl.c \
bog_lib_negativ.c bog_normalize_ARITY.h bog_unflatten_abl.h \
bog_lib_negativ.h bog_normalize_DAG.c bog_unflatten_area.c \
bog_lib_permute.c bog_normalize_DAG.h bog_unflatten_area.h \
bog_lib_permute.h bog_normalize_DC.c bog_unflatten_befig.c \
bog_lib_reader.c bog_normalize_DC.h bog_unflatten_befig.h \
bog_lib_reader.h bog_normalize_message.c bog_unflatten_delay.c \
bog_lib_specifications.c bog_normalize_message.h bog_unflatten_delay.h \
bog_lib_specifications.h bog_normalize_nameindex.c bog_unflatten_oper.c \
bog_lib_utils.c bog_normalize_nameindex.h bog_unflatten_oper.h \
bog_lib_utils.h bog_normalize_power.c bog_unflatten_utils.c \
bog_main.c bog_normalize_power.h bog_unflatten_utils.h \
bog_map_abl.c bog_normalize_register.c bog_xsch_driver.c \
bog_map_abl.h bog_normalize_register.h bog_xsch_driver.h \
bog_map_adapt.c bog_normalize_simplify.c

File diff suppressed because it is too large Load Diff

View File

@ -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 Boog - 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 float getdelaylax __P ((char *name));
/***************************************************************************/
/* return the impedance(R in Ohm) of name for an input in lax file */
/***************************************************************************/
extern float getimpedancelax __P ((char *name));
/***************************************************************************/
/* return the fanout(C in pF exp-12) of name for an output in lax file */
/***************************************************************************/
extern float 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 befig */
/* lokk if all referenced names are in befig */
/***************************************************************************/
extern int coherencelax __P ((befig_list* befig));
#endif

View File

@ -0,0 +1,206 @@
/*
* 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 : BooG - library cells
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <mlo.h>
#include <abl.h>
#include <abe.h>
#include "bog_normalize_ARITY.h"
#include "bog_lib_utils.h"
#include "bog_lib_complete.h"
#include "bog_map_pattern.h"
#include "bog_lib_cell.h"
/*table of cells*/
static cell_list* LOGIC_CELLS=NULL;
static cell_list* REG_CELLS=NULL;
static cell_list* BUS_CELLS=NULL;
/*flag to signal the presence of tristate inverter in library*/
static int TRISTATE_INVERTER=0;
/******************************************************************************/
/* return the list of flip-flop and latch cells */
/******************************************************************************/
extern cell_list* getcell_register_lib()
{
return REG_CELLS;
}
/******************************************************************************/
/* return the list of tristate cells */
/******************************************************************************/
extern cell_list* getcell_tristate_lib()
{
return BUS_CELLS;
}
/******************************************************************************/
/* return the list of pure logical cells */
/******************************************************************************/
extern cell_list* getcell_logic_lib()
{
return LOGIC_CELLS;
}
/******************************************************************************/
/* set the list of register cells */
/******************************************************************************/
extern void setcell_register_lib __P ((cell_list* cells_lib))
{
REG_CELLS=cells_lib;
}
/******************************************************************************/
/* set the list of tristate cells */
/******************************************************************************/
extern void setcell_tristate_lib __P ((cell_list* cells_lib))
{
BUS_CELLS=cells_lib;
}
/******************************************************************************/
/* set the list of pure logical cells */
/******************************************************************************/
extern void setcell_logic_lib __P ((cell_list* cells_lib))
{
LOGIC_CELLS=cells_lib;
}
/******************************************************************************/
/*add a pure logic cell */
/*return the new cell if inserted in library else return NULL */
/******************************************************************************/
extern cell_list* addCell_logic(befig_list* befig, chain_list* abl)
{
cell_list* cell, *list;
cell=addCell(befig);
/*ABL field isn't a real abl!!!*/
cell->ABL=build_reference(befig,cell->PORT,NULL,abl);
put_arity_abl(cell->ABL);
/*memorize and sort in global variable*/
list=classCell(cell,LOGIC_CELLS);
if (list) LOGIC_CELLS=list;
return list?cell:NULL;
}
/******************************************************************************/
/*build a new bus cell in our library */
/*return the new cell if inserted in library else return NULL */
/******************************************************************************/
extern cell_list* addCell_bus(befig_list* befig, biabl_list* biabl)
{
cell_list* cell;
cell_list* list;
cell=addCell(befig);
cell->BIABL=biabl;
for ( ; biabl; biabl=biabl->NEXT) {
/*VALABL,CNDABL fields aren't real abl!!!*/
biabl->VALABL=build_reference(befig,cell->PORT,NULL,biabl->VALABL);
biabl->CNDABL=build_reference(befig,cell->PORT,NULL,biabl->CNDABL);
put_arity_abl(biabl->VALABL);
put_arity_abl(biabl->CNDABL);
/*mark if it is a tristate inverter with a simple condition*/
if (!ABL_ATOM(biabl->VALABL) && ABL_OPER(biabl->VALABL)==ABL_NOT) {
TRISTATE_INVERTER=1;
}
}
/*memorize and sort in global variable*/
list=classCell(cell,BUS_CELLS);
if (list) BUS_CELLS=list;
return list?cell:NULL;
}
/******************************************************************************/
/*build a new flip-flop or latch cell in our library */
/*return the new cell if inserted in library else return NULL */
/******************************************************************************/
extern cell_list* addCell_register(befig_list* befig, biabl_list *biabl)
{
cell_list* cell, *list;
port_list* internal_reg_port=NULL, *port;
cell=addCell(befig);
cell->BIABL=biabl;
for ( ; biabl; biabl=biabl->NEXT) {
/*create internal reference to register*/
internal_reg_port=internal_reference(befig,internal_reg_port,biabl->VALABL);
internal_reg_port=internal_reference(befig,internal_reg_port,biabl->CNDABL);
/*VALABL,CNDABL fields aren't real abl!!!*/
biabl->VALABL=build_reference(befig,cell->PORT,internal_reg_port,biabl->VALABL);
biabl->CNDABL=build_reference(befig,cell->PORT,internal_reg_port,biabl->CNDABL);
put_arity_abl(biabl->VALABL);
put_arity_abl(biabl->CNDABL);
}
/*memorize and sort in global variable*/
list=classCell(cell,REG_CELLS);
if (list) REG_CELLS=list;
return list?cell:NULL;
}
/******************************************************************************/
/* return 1 if a tristate inverter exists in library */
/******************************************************************************/
extern int is_tristate_inverter_lib()
{
return TRISTATE_INVERTER;
}

View File

@ -0,0 +1,99 @@
/*
* 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 : BooG - library cells
* Date : 2000
* Author : Francois Donnet
*/
#ifndef LIB_CELL_H
#define LIB_CELL_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/******************************************************************************/
/*add a pure logic cell */
/*return the new cell if inserted in library else return NULL */
/******************************************************************************/
extern cell_list* addCell_logic __P ((befig_list* befig, chain_list* abl));
/******************************************************************************/
/*build a new bus cell in our library */
/*return the new cell if inserted in library else return NULL */
/******************************************************************************/
extern cell_list* addCell_bus __P ((befig_list* befig, biabl_list* biabl));
/******************************************************************************/
/*build a new flip-flop or latch cell in our library */
/*return the new cell if inserted in library else return NULL */
/******************************************************************************/
extern cell_list* addCell_register __P ((befig_list* befig, biabl_list *biabl));
/******************************************************************************/
/* return the list of register cells */
/******************************************************************************/
extern cell_list* getcell_register_lib __P (());
/******************************************************************************/
/* return the list of tristate cells */
/******************************************************************************/
extern cell_list* getcell_tristate_lib __P (());
/******************************************************************************/
/* return the list of pure logical cells */
/******************************************************************************/
extern cell_list* getcell_logic_lib __P (());
/******************************************************************************/
/* set the list of register cells */
/******************************************************************************/
extern void setcell_register_lib __P ((cell_list* cells_lib));
/******************************************************************************/
/* set the list of tristate cells */
/******************************************************************************/
extern void setcell_tristate_lib __P ((cell_list* cells_lib));
/******************************************************************************/
/* set the list of pure logical cells */
/******************************************************************************/
extern void setcell_logic_lib __P ((cell_list* cells_lib));
/******************************************************************************/
/* return 1 if a tristate inverter exists in library */
/******************************************************************************/
extern int is_tristate_inverter_lib __P (());
#endif

View File

@ -0,0 +1,566 @@
/*
* 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 : BooG - library completion
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <mlo.h>
#include <abl.h>
#include <abe.h>
#include "bog_lax_param.h"
#include "bog_normalize_ARITY.h"
#include "bog_lib_specifications.h"
#include "bog_lib_utils.h"
#include "bog_lib_cell.h"
#include "bog_map_befig.h"
#include "bog_map_pattern.h"
#include "bog_signal_utils.h"
#include "bog_lib_complete.h"
/*to memorize kind of operator: dual cells with different arities*/
typedef struct dual{
struct dual *NEXT;
int OPER; /*oper expected*/
int ARITY;
cell_list *CELL;
cell_list *NEG_CELL; /*negation of expected*/
} dual_list;
/*simple operator n1_y, a2_y, a3_y, xor, or, nand3, nxr2 ...*/
static cell_list* SIMPLE_OPER;
/******************************************************************************/
/* add a cell in a sorted list of dual cells */
/******************************************************************************/
static dual_list* add_dual(dual_list* top, cell_list* cell)
{
dual_list* dual, *pred=NULL, *new;
/*search place*/
for (dual=top; dual; dual=dual->NEXT) {
if (dual->ARITY>=ABL_ARITY(cell->ABL)) break;
pred=dual;
}
/*insert if possible*/
if (dual && dual->ARITY==ABL_ARITY(cell->ABL)) {
/*not the operator wanted!*/
if (dual->OPER!=ABL_OPER(cell->ABL)
&& (!dual->CELL || ABL_OPER(cell->ABL)!=ABL_OPER(dual->CELL->ABL))){
fprintf(stderr,
"add_dual: computing error on cell with oper %s and %s (arity %d)\n",
getabloperuppername(ABL_OPER(cell->ABL)),
getabloperuppername(dual->OPER),ABL_ARITY(cell->ABL));
exit(1);
}
/*memo new cell*/
if (dual->OPER==ABL_OPER(cell->ABL)) {
/*if already one take the littlest*/
if (!dual->NEG_CELL || cell->AREA<dual->NEG_CELL->AREA)
dual->NEG_CELL=cell;
}
else {
/*if already one take the littlest*/
if (!dual->CELL || cell->AREA<dual->CELL->AREA)
dual->CELL=cell;
}
return top;
}
new=mbkalloc(sizeof(dual_list));
new->NEXT=dual;
new->NEG_CELL=NULL;
new->CELL=cell;
new->ARITY=ABL_ARITY(cell->ABL);
switch (ABL_OPER(cell->ABL)) {
case ABL_AND: new->OPER=ABL_NAND; break; /*oper expected*/
case ABL_NAND: new->OPER=ABL_AND; break;
case ABL_OR: new->OPER=ABL_NOR; break;
case ABL_NOR: new->OPER=ABL_OR; break;
case ABL_XOR: new->OPER=ABL_NXOR; break;
case ABL_NXOR: new->OPER=ABL_XOR; break;
}
if (!pred) return new;
pred->NEXT=new;
return top;
}
/******************************************************************************/
/* free recursively a list of dual cell */
/******************************************************************************/
static void free_dual(dual_list* top)
{
if (!top) return;
free_dual(top->NEXT);
mbkfree(top);
}
/******************************************************************************/
/*to improve speed of unflattening algorithm */
/*isolate simple operator */
/******************************************************************************/
static void simpleCell(cell_list* cell)
{
chain_list* abl;
cell_list* new, *list;
/*only pure logic*/
if (cell->BIABL) return;
/*no constant*/
if (ABL_ATOM(cell->ABL)) return;
/*control all leaves are atomic*/
for (abl=ABL_CDR(cell->ABL); abl; abl=ABL_CDR(abl)) {
if (!ABL_ATOM(ABL_CAR(abl))) return;
/*constant forbidden*/
if (ABL_ATOM_VALUE(ABL_CAR(abl))==getablatomone()) return;
if (ABL_ATOM_VALUE(ABL_CAR(abl))==getablatomzero()) return;
}
new=copyCell(cell);
/*sort list (return NULL if not inserted)*/
list=classCell(new,SIMPLE_OPER);
if (list) SIMPLE_OPER=list;
}
/***************************************************************************/
/* return the area of cells matching abl */
/***************************************************************************/
static int addgeneric(chain_list *abl, befig_list* befig, int area, float R, float C, float T)
{
port_list* port;
cell_list* cell;
if (ABL_ATOM(abl)) {
if (ABL_ATOM_VALUE(abl)!=getablatomone()
&& ABL_ATOM_VALUE(abl)!=getablatomzero()) {
putgenericT(befig,ABL_ATOM_VALUE(abl),T,T,T,T);
putgenericR(befig,ABL_ATOM_VALUE(abl),R,R);
putgenericC(befig,ABL_ATOM_VALUE(abl),C);
}
return area;
}
/*cell->PORT contains the result of pattern matching*/
cell=cell_pattern(abl);
for (port=cell->PORT; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case OUT: case TRISTATE:
/*no delay for output*/
break;
case IN: case INOUT: case TRANSCV:
area=addgeneric(port->ABL, befig, area, R==0?port->R/*gate on top*/:R,
port->C /*last gate concerned*/, T + port->T + port->R*C);
break;
}
}
return area+cell->AREA;
}
/******************************************************************************/
/* put the bepor with the leaf of abl */
/******************************************************************************/
static void addinput(befig_list* befig, chain_list *abl)
{
bepor_list* bepor;
if (!befig || !abl) {
fprintf(stderr,"addinput: NULL pointer\n");
exit(1);
}
if (ABL_ATOM(abl)) {
if (ABL_ATOM_VALUE(abl)==getablatomone()) return;
if (ABL_ATOM_VALUE(abl)==getablatomzero()) return;
/*already defined*/
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
if (bepor->NAME==ABL_ATOM_VALUE(abl)) return;
}
befig->BEPOR=beh_addbepor(befig->BEPOR,ABL_ATOM_VALUE(abl),IN,'B');
befig->BERIN=beh_addberin(befig->BERIN,ABL_ATOM_VALUE(abl));
return;
}
for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) {
addinput(befig,ABL_CAR(abl));
}
}
/******************************************************************************/
/* return a befig with abl_out for output and without beaux */
/* build also a lofig to use as if it was a cell in library */
/*when you build a cell with this befig to complete a library, you must put */
/*the flag MODE of the cell resulting to 'A' (for later mapping) */
/******************************************************************************/
static befig_list* complete_lib(char* name, chain_list* abl_out)
{
befig_list* befig;
char *out_name;
int area;
bepor_list* bepor;
beaux_list* beaux;
bebux_list* bebux;
bereg_list* bereg;
beout_list* beout;
if (!name || !abl_out) {
fprintf(stderr,"complete_lib: NULL pointer\n");
exit(1);
}
name=namealloc(name);
befig=beh_addbefig(NULL,name);
out_name=namealloc("f");
befig->BEOUT=beh_addbeout(NULL,out_name,abl_out,NULL);
/*put arity oper*/
put_arity(befig);
befig->BEPOR=beh_addbepor(befig->BEPOR,VSS,IN,'B');
befig->BEPOR=beh_addbepor(befig->BEPOR,VDD,IN,'B');
befig->BEPOR=beh_addbepor(befig->BEPOR,out_name,OUT,'B');
/*all inputs*/
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
addinput(befig,beout->ABL);
}
/*define all signals*/
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) putdelay(bepor->NAME,0);
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) putdelay(beaux->NAME,0);
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) putdelay(bereg->NAME,0);
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) putdelay(bebux->NAME,0);
putdelay(getablatomone(),0);
putdelay(getablatomzero(),0);
area=addgeneric(befig->BEOUT->ABL,befig,0,0,0,0);
putgenericarea(befig,area);
/*create a lofig*/
map_befig(befig,befig->NAME);
/*undefine all signals not to interfer with work*/
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) undefdelay(bepor->NAME);
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) undefdelay(beaux->NAME);
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) undefdelay(bereg->NAME);
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) undefdelay(bebux->NAME);
undefdelay(getablatomone());
undefdelay(getablatomzero());
return befig;
}
/******************************************************************************/
/* return a cell with the opposite behave of cell */
/******************************************************************************/
static cell_list* complete_neg_lib(cell_list* cell)
{
chain_list *out_abl, *abl;
char *name;
char memo;
befig_list *befig, *new;
if (!cell) {
fprintf(stderr,"complete_neg_lib: NULL pointer\n");
exit(1);
}
befig=cell->BEFIG;
if (!befig || !befig->BEOUT || !befig->BEOUT->ABL) {
fprintf(stderr,"complete_neg_lib: NULL pointer\n");
exit(1);
}
out_abl=createablnotexpr(dupablexpr(befig->BEOUT->ABL));
memo=SEPAR;
SEPAR='_';
name=concatname("not",cell->NAME);
SEPAR=memo;
new=complete_lib(name,out_abl);
abl=dupablexpr(createablnotexpr(befig->BEOUT->ABL)); /* f<= not oper (i) */
abl=simpablexpr(abl); /* f<= noper (i) */
put_arity_abl(abl);
/*put in library*/
return addCell_logic(new,abl);
}
/******************************************************************************/
/* return a cell generating XOR */
/******************************************************************************/
static cell_list* complete_xor_lib()
{
chain_list *out_abl, *abl1, *abl2, *abl;
chain_list *i0, *i1, *ni1, *ni0;
befig_list *new;
i0=createablatom(namealloc("i0"));
i1=createablatom(namealloc("i1"));
ni0=createablnotexpr(dupablexpr(i0));
ni1=createablnotexpr(dupablexpr(i1));
abl1=createablbinexpr(ABL_NOR,i0,ni1);
abl2=createablbinexpr(ABL_NOR,ni0,i1);
out_abl=createablbinexpr(ABL_NAND,abl1,abl2);
/*create befig and lofig*/
new=complete_lib(namealloc("xr2_y"),out_abl);
abl=createablbinexpr(ABL_XOR, createablatom(namealloc("i0")),
createablatom(namealloc("i1")));
put_arity_abl(abl);
/*put in library*/
return addCell_logic(new,abl);
}
/******************************************************************************/
/* return a cell generating NXOR */
/******************************************************************************/
static cell_list* complete_nxor_lib()
{
chain_list *out_abl, *abl1, *abl2, *abl;
chain_list *i0, *i1, *ni1, *ni0;
befig_list *new;
i0=createablatom(namealloc("i0"));
i1=createablatom(namealloc("i1"));
ni0=createablnotexpr(dupablexpr(i0));
ni1=createablnotexpr(dupablexpr(i1));
abl1=createablbinexpr(ABL_NOR,i0,ni1);
abl2=createablbinexpr(ABL_NOR,ni0,i1);
out_abl=createablbinexpr(ABL_AND,abl1,abl2);
/*create befig and lofig*/
new=complete_lib(namealloc("nxr2_y"),out_abl);
abl=createablbinexpr(ABL_XOR, createablatom(namealloc("i0")),
createablatom(namealloc("i1")));
put_arity_abl(abl);
/*put in library*/
return addCell_logic(new,abl);
}
/******************************************************************************/
/* control if there is a NOT, a AND, a OR */
/* complete the library if some cells are missing */
/******************************************************************************/
extern void control_lib()
{
cell_list* not=NULL; /*flag*/
cell_list* buff=NULL; /*flag*/
cell_list* one=NULL; /*flag*/
cell_list* zero=NULL; /*flag*/
dual_list* or=NULL;
dual_list* and=NULL;
dual_list* xor=NULL;
dual_list* dual;
cell_list* cell;
int arity;
for (cell=getcell_logic_lib(); cell; cell=cell->NEXT) {
simpleCell(cell); /*build SIMPLE_OPER variable*/
if (ABL_ATOM(cell->ABL)) {
if (ABL_ATOM_VALUE(cell->ABL)==getablatomone()) one=cell;
else if (ABL_ATOM_VALUE(cell->ABL)==getablatomzero()) zero=cell;
else buff=cell;
}
}
for (cell=SIMPLE_OPER; cell; cell=cell->NEXT) {
switch ABL_OPER(cell->ABL) {
case ABL_AND: case ABL_NAND: and=add_dual(and,cell); break;
case ABL_NOR: case ABL_OR: or=add_dual(or,cell); break;
case ABL_XOR: case ABL_NXOR: xor=add_dual(xor,cell); break;
case ABL_NOT: not=cell; break;
default:
fprintf(stderr,"control_lib: unknow oper %ld\n",
ABL_OPER(cell->ABL));
exit(1);
}
}
if (!one) {
fprintf(stderr,
"Mapping Warning: 'ONE' constant cell is missing in library\n");
}
if (!zero) {
fprintf(stderr,
"Mapping Warning: 'ZERO' constant cell is missing in library\n");
}
if (!not) {
fprintf(stderr,"Mapping Error: 'NOT' cell is missing in library\n");
exit(1);
}
if (!or) {
fprintf(stderr,"Mapping Error: 'OR' cell is missing in library\n");
exit(1);
}
else if (or->ARITY!=2) {
fprintf(stderr,
"Mapping Error: 'OR 2' is missing in library\n");
exit(1);
}
if (!and) {
fprintf(stderr,"Mapping Error: 'AND' cell is missing in library\n");
exit(1);
}
else if (and->ARITY!=2) {
fprintf(stderr,
"Mapping Error: 'AND 2' is missing in library\n");
exit(1);
}
if (xor && xor->ARITY!=2) {
fprintf(stderr,
"Mapping Error: 'XOR 2' is missing in library\n");
exit(1);
}
arity=2;
for (dual=and; dual; dual=dual->NEXT) {
if (!dual->NEG_CELL) {
fprintf(stderr,
"Mapping Warning: a '%s%d' is missing in cell library...Generating\n",
getabloperuppername(dual->OPER), dual->ARITY);
/*build a buffer with 2 inverters*/
cell=complete_neg_lib(dual->CELL);
if (cell) {
cell->MODE='A'; /*doesn't really exist in lib*/
simpleCell(cell); /*build SIMPLE_OPER variable*/
}
}
arity++;
}
arity=2;
for (dual=or; dual; dual=dual->NEXT) {
if (!dual->NEG_CELL) {
fprintf(stderr,
"Mapping Warning: a '%s%d' is missing in cell library...Generating\n",
getabloperuppername(dual->OPER), dual->ARITY);
/*build a buffer with 2 inverters*/
cell=complete_neg_lib(dual->CELL);
if (cell) {
cell->MODE='A'; /*doesn't really exist in lib*/
simpleCell(cell); /*build SIMPLE_OPER variable*/
}
}
arity++;
}
arity=2;
for (dual=xor; dual; dual=dual->NEXT) {
if (!dual->NEG_CELL) {
fprintf(stderr,
"Mapping Warning: a '%s%d' is missing in cell library...Generating\n",
getabloperuppername(dual->OPER), dual->ARITY);
/*build a buffer with 2 inverters*/
cell=complete_neg_lib(dual->CELL);
if (cell) {
cell->MODE='A'; /*doesn't really exist in lib*/
simpleCell(cell); /*build SIMPLE_OPER variable*/
}
}
arity++;
}
/*if buffer doesn't exist, build*/
if (!buff) {
fprintf(stderr,
"Mapping Warning: a buffer is missing in cell library...Generating\n");
/*build a buffer with 2 inverters*/
cell=complete_neg_lib(not);
if (cell) {
cell->MODE='A'; /*doesn't really exist in lib*/
simpleCell(cell); /*build SIMPLE_OPER variable*/
}
}
/*if xor doesn't exist, build*/
if (!xor) {
fprintf(stderr,
"Mapping Warning: 'xor' is missing in cell library...Generating\n");
cell=complete_xor_lib();
if (cell) {
cell->MODE='A'; /*doesn't really exist in lib*/
simpleCell(cell); /*build SIMPLE_OPER variable*/
}
cell=complete_nxor_lib();
if (cell) {
cell->MODE='A'; /*doesn't really exist in lib*/
simpleCell(cell); /*build SIMPLE_OPER variable*/
}
}
free_dual(xor);
free_dual(and);
free_dual(or);
}
/***************************************************************************/
/* return the list of simple oper of the library */
/***************************************************************************/
extern cell_list* getcell_oper_lib()
{
return SIMPLE_OPER;
}

View File

@ -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 : BooG - library completion
* Date : 2000
* Author : Francois Donnet
*/
#ifndef LIB_COMPLETE_H
#define LIB_COMPLETE_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/******************************************************************************/
/* control if there is a NOT, a AND, a OR */
/* complete the library if some cells are missing */
/******************************************************************************/
extern void control_lib __P (());
/***************************************************************************/
/* return the list of simple oper of the library */
/***************************************************************************/
extern cell_list* getcell_oper_lib __P (());
#endif

View File

@ -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 : BooG - 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 "bog_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* abl, biabl_list* biabl)
{
bepor_list* bepor;
biabl_list* biabl_aux;
/*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,abl)) {
for (biabl_aux=biabl; biabl_aux; biabl_aux=biabl_aux->NEXT) {
if (is_input_used(bepor->NAME,biabl_aux->VALABL)
|| is_input_used(bepor->NAME,biabl_aux->CNDABL)) break;
}
if (biabl_aux) continue;
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)
{
biabl_list* biabl;
/*internal signal forbidden*/
if (befig->BEAUX) return 0;
if (befig->BEREG) {
/*only one register*/
if (befig->BEREG->NEXT || befig->BEBUS || befig->BEBUX) 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);
for (biabl=befig->BEREG->BIABL; biabl; biabl=biabl->NEXT) {
biabl->VALABL=simpablexpr(createablnotexpr(biabl->VALABL));
}
}
return used_inputs(befig,NULL,
befig->BEREG->BIABL);
}
if (befig->BEBUS) {
/*only one bus*/
if (befig->BEBUS->NEXT || befig->BEREG || befig->BEBUX) return 0;
/*one ouput: bebus*/
if (befig->BEOUT) return 0;
return used_inputs(befig,NULL,
befig->BEBUS->BIABL);
}
if (befig->BEBUX) {
/*only one internal bus*/
if (befig->BEBUX->NEXT || befig->BEREG || befig->BEBUS) 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);
for (biabl=befig->BEBUX->BIABL; biabl; biabl=biabl->NEXT) {
biabl->VALABL=simpablexpr(createablnotexpr(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,NULL,
befig->BEBUS->BIABL);
}
if (befig->BEOUT) {
/*one ouput: beout*/
if (befig->BEOUT->NEXT || befig->BEBUS) 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;
}

View File

@ -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 : BooG - 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

View File

@ -0,0 +1,146 @@
/*
* 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 : BooG - 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 "bog_normalize_ARITY.h"
#include "bog_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;
if (ABL_ARITY (expr) != ABL_ARITY (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;
}

View File

@ -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 : BooG - 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));
#endif

View File

@ -0,0 +1,234 @@
/*
* 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 : BooG - negativ operands
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <abl.h>
#include <abe.h>
#include "bog_normalize_ARITY.h"
#include "bog_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);
ABL_ARITY(abl)=1;
}
}
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;
case ABL_STABLE:
if (negativ) {
abl=createablnotexpr(abl);
ABL_ARITY(abl)=1;
}
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=NULL, *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);
}
if (ABL_OPER(abl)==ABL_STABLE) return 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: case ABL_STABLE: to_let++; break;
case ABL_XOR: case ABL_NXOR: /*undifferent*/ break;
default:
fprintf(stderr,"build_negativ: 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) {
/*no advantage to invert*/
switch (ABL_OPER(abl)) {
case ABL_NAND: case ABL_NOR: return abl;
}
}
/*forbidden to invert*/
switch (ABL_OPER(abl)) {
case ABL_STABLE:
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));
ABL_ARITY(ABL_CAR(chain))=1;
}
continue;
}
else if (ABL_OPER(leaf)==ABL_STABLE) {
ABL_CAR(chain)=createablnotexpr(ABL_CAR(chain));
ABL_ARITY(ABL_CAR(chain))=1;
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,"build_negativ: 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_NOT:
chain=abl;
abl=ABL_CADR(abl);
freechain(chain);
break;
default:
fprintf(stderr,"build_negativ: oper %ld unknown\n",ABL_OPER(leaf));
exit(1);
}
return abl;
}

View File

@ -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 : BooG - 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

View File

@ -0,0 +1,452 @@
/*
* 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 : BooG - tree permutations
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <abl.h>
#include <abe.h>
#include "bog_normalize_ARITY.h"
#include "bog_lib_matching.h"
#include "bog_lib_specifications.h"
#include "bog_lib_utils.h"
#include "bog_lib_permute.h"
/******************************************************************************/
/* duplicate a list */
/******************************************************************************/
extern 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;
}
/******************************************************************************/
/* duplicate a list of abl and its abl */
/******************************************************************************/
static chain_list* dupablchain(chain_list* ablchain)
{
chain_list* chain,*res=NULL;
for (chain=ablchain;chain;chain=chain->NEXT) {
res=addchain(res,dupablexpr(chain->DATA));
}
return res;
}
/******************************************************************************/
/*return a list of list with elem inserted in all positions of elem_chain */
/*result is put at the top of head_positions */
/******************************************************************************/
extern chain_list *all_positions(chain_list* head_positions, chain_list* elem_chain, void* elem)
{
chain_list *chain, *pred=NULL;
chain_list *other_positions;
if (!elem_chain)
{
elem_chain=addchain(NULL,elem);
head_positions=addchain(head_positions, elem_chain);
return head_positions;
}
/*put in other places*/
other_positions=all_positions(NULL, elem_chain->NEXT, elem);
/*complete the result*/
for (chain=other_positions; chain; chain=chain->NEXT) {
chain->DATA=addchain(chain->DATA, elem_chain->DATA);
pred=chain;
}
/*put at the top*/
pred->NEXT=head_positions;
head_positions=other_positions;
/*put in first place*/
elem_chain=addchain(dupchain(elem_chain),elem);
head_positions=addchain(head_positions, elem_chain);
return head_positions;
}
/******************************************************************************/
/* return a list of list of elements */
/*which compose all the possible different orders of elem_chain */
/* elements aren't duplicated */
/* result is put at the top of head_swap */
/******************************************************************************/
static chain_list *swapchain_aux(chain_list* head_swap, chain_list* elem_chain)
{
chain_list *chain;
void *elem;
chain_list *other_swap;
if (!elem_chain) return NULL;
other_swap=swapchain_aux(NULL, elem_chain->NEXT);
elem=elem_chain->DATA;
if (!other_swap) return all_positions(head_swap, NULL, elem);
for (chain=other_swap; chain; chain=chain->NEXT) {
head_swap=all_positions(head_swap, chain->DATA, elem);
}
freechain(other_swap);
return head_swap;
}
/******************************************************************************/
/* return a list of list of elements */
/*which compose all the possible different orders of elem_chain */
/* elements aren't duplicated */
/******************************************************************************/
extern chain_list *swapchain(chain_list* elem_chain)
{
return swapchain_aux(NULL, elem_chain);
}
/******************************************************************************/
/*parameter is a list of element list: for a place of the final list, several */
/*elements are possible */
/* return a list of element chain based on all choices proposed in parameter */
/******************************************************************************/
static chain_list* composechain_aux(chain_list* elem_chain_chain)
{
void *elem;
chain_list *elem_chain, *other_elem_chain, *current_elem_chain;
chain_list *chain;
chain_list *head_elem_chain=NULL;
/*the list is empty*/
if (!elem_chain_chain) return addchain(NULL,NULL);
other_elem_chain=composechain_aux(elem_chain_chain->NEXT);
/*several elements for this place*/
for (elem_chain=elem_chain_chain->DATA; elem_chain; elem_chain=elem_chain->NEXT) {
elem=elem_chain->DATA;
/*build new list with these choices*/
for (chain=other_elem_chain; chain; chain=chain->NEXT) {
current_elem_chain = chain->DATA;
current_elem_chain = dupchain(current_elem_chain);
current_elem_chain = addchain(current_elem_chain, elem);
head_elem_chain = addchain(head_elem_chain, current_elem_chain);
}
}
/*free mem*/
for (chain=other_elem_chain; chain; chain=chain->NEXT) freechain(chain->DATA);
freechain(other_elem_chain);
return head_elem_chain;
}
/******************************************************************************/
/*parameter is a list of element list: for each place of the final list, */
/*several elements are possible */
/* return a list of element chain based on all choices proposed in parameter */
/******************************************************************************/
extern chain_list* composechain(chain_list* elem_chain_chain)
{
chain_list* compose_chain;
chain_list* head_swap_chain=NULL;
chain_list* chain, *elem_chain;
/*build all the possible abl with this choice of leaves*/
compose_chain=composechain_aux(elem_chain_chain);
/*build all permutations with this composition*/
for (chain=compose_chain; chain; chain=chain->NEXT) {
elem_chain=chain->DATA;
/*list of permutations with these elements of ablchain*/
/*add it to final result*/
head_swap_chain=swapchain_aux(head_swap_chain, elem_chain);
}
freechain(compose_chain);
return head_swap_chain;
}
/******************************************************************************/
/*return a list of abl. It is the list of all possible permutations of an abl */
/*abl parameter isn't deleted */
/******************************************************************************/
static chain_list *permutations_abl(chain_list* abl)
{
chain_list *head, *list_abl;
chain_list *permutations_leaves_list=NULL;
chain_list *chain, *chain2;
/*leaf*/
if (ABL_ATOM(abl)) return addchain(NULL,dupablexpr(abl));
/*build first permutations on leaves and get back*/
for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
/*list of list of permutated leaves*/
permutations_leaves_list=addchain(permutations_leaves_list,
permutations_abl(ABL_CAR(chain)));
}
/*build all the possible abl with this choice of leaves*/
list_abl=composechain(permutations_leaves_list);
/*put the operator*/
for (chain=list_abl; chain; chain=chain->NEXT) {
head=createabloper(ABL_OPER(abl));
ABL_ARITY(head)=ABL_ARITY(abl);
ABL_CDR(head)=dupablchain(chain->DATA);
chain->DATA=head;
}
/*free previous search*/
for (chain=permutations_leaves_list; chain; chain=chain->NEXT) {
for (chain2=chain->DATA; chain2; chain2=chain2->NEXT) {
freeablexpr(chain2->DATA);
}
freechain(chain->DATA);
}
freechain(permutations_leaves_list);
return list_abl;
}
/******************************************************************************/
/* return 1 if abl1 and abl2 heave the same properties */
/******************************************************************************/
static int same_properties(chain_list* abl1, chain_list* abl2, befig_list* befig)
{
if (ABL_ATOM(abl1)!=ABL_ATOM(abl2)) {
fprintf(stderr,"same_properties: compute error\n");
exit(1);
}
if (ABL_ATOM(abl1)) {
/*no use to compare if the same leaf*/
if (ABL_ATOM_VALUE(abl1)==ABL_ATOM_VALUE(abl2)) return 0;
/*comparison*/
if (getgenericT(befig,ABL_ATOM_VALUE(abl1))
!=getgenericT(befig,ABL_ATOM_VALUE(abl2))) return 0;
if (getgenericR(befig,ABL_ATOM_VALUE(abl1)) /* Rup+Rdown/2 */
!=getgenericR(befig,ABL_ATOM_VALUE(abl2))) return 0;
if (getgenericC(befig,ABL_ATOM_VALUE(abl1)) /* entry Capacitance */
!=getgenericC(befig,ABL_ATOM_VALUE(abl2))) return 0;
return 1; /*equality*/
}
/*operator*/
abl2=ABL_CDR(abl2);
for (abl1=ABL_CDR(abl1); abl1; abl1=ABL_CDR(abl1)) {
if (!same_properties(ABL_CAR(abl1),ABL_CAR(abl2),befig)) return 0;
abl2=ABL_CDR(abl2);
}
return 0; /*equality*/
}
/******************************************************************************/
/* return the list of different abl resulting of permutations */
/******************************************************************************/
extern chain_list* different_abl(befig_list* befig, chain_list* abl)
{
chain_list* list_abl;
/*get all permutations possible*/
list_abl=permutations_abl(abl);
#if 0 /*no use, all abl are different*/
bepor_list *bepor, *bepor_aux;
chain_list* chain;
chain_list* control, *pred;
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
if (isvdd(bepor->NAME) || isvss(bepor->NAME)) continue;
if (bepor->DIRECTION=='O' || bepor->DIRECTION=='Z') continue;
for (bepor_aux=befig->BEPOR; bepor_aux; bepor_aux=bepor_aux->NEXT) {
if (isvdd(bepor_aux->NAME) || isvss(bepor_aux->NAME)) continue;
if (bepor_aux->DIRECTION=='O' || bepor_aux->DIRECTION=='Z') continue;
/*search a leaves with equal properties*/
if (getgenericT(befig,bepor->NAME)==getgenericT(befig,bepor_aux->NAME)
&& getgenericR(befig,bepor->NAME)==getgenericR(befig,bepor_aux->NAME)
&& getgenericC(befig,bepor->NAME)==getgenericC(befig,bepor_aux->NAME)){
/*put off duplicate use*/
for (control=list_abl; control; control=control->NEXT) {
pred=control;
for (chain=control->NEXT; chain; chain=chain->NEXT) {
/*erase doublon*/
if (same_properties(control->DATA,chain->DATA,befig)) {
freeablexpr(chain->DATA);
pred->NEXT=chain->NEXT;
chain->NEXT=NULL;
freechain(chain);
chain=pred;
}
pred=chain;
}
} /*end of loop*/
}
}/*end of loop*/
}/*end of loop*/
#endif
return list_abl;
}
/***************************************************************************/
/* return the list of different biabl resulting of permutations */
/***************************************************************************/
static chain_list* permutations_biabl(biabl_list* biabl)
{
chain_list *permutations_val, *permutations_cnd;
chain_list *chain_cnd, *chain_val, *permute=NULL;
chain_list *head_biabl_chain=NULL, *swap_biabl;
chain_list *permutations_biabl, *chain, *order;
biabl_list *biabl_aux;
chain_list *mem_permutations=NULL;
for ( ; biabl; biabl=biabl->NEXT) {
/*give the list of different permutations*/
permutations_cnd=permutations_abl(biabl->CNDABL);
permutations_val=permutations_abl(biabl->VALABL);
mem_permutations=addchain(mem_permutations,permutations_cnd);
mem_permutations=addchain(mem_permutations,permutations_val);
permutations_biabl=NULL;
/*put in cell*/
for (chain_cnd=permutations_cnd; chain_cnd; chain_cnd=chain_cnd->NEXT) {
for (chain_val=permutations_val; chain_val; chain_val=chain_val->NEXT) {
biabl_aux=beh_addbiabl(NULL, biabl->LABEL, chain_cnd->DATA,
chain_val->DATA);
biabl_aux->USER=biabl->USER;
permutations_biabl=addchain(permutations_biabl, biabl_aux);
}
}
permute=addchain(permute, permutations_biabl);
}
/*swap*/
swap_biabl=composechain(permute);
/*build real biabl*/
for (chain=swap_biabl; chain; chain=chain->NEXT) {
biabl_aux=NULL;
for (order=chain->DATA; order; order=order->NEXT) {
biabl=(biabl_list*) order->DATA;
biabl_aux=beh_addbiabl(biabl_aux, biabl->LABEL, dupablexpr(biabl->CNDABL),
dupablexpr(biabl->VALABL));
biabl_aux->USER=biabl->USER;
}
biabl_aux=(biabl_list*) reverse((chain_list*) biabl_aux);
head_biabl_chain=addchain(head_biabl_chain, biabl_aux);
}
/*free memory*/
for (chain=permute; chain; chain=chain->NEXT) {
permutations_biabl=chain->DATA;
for (order=permutations_biabl; order; order=order->NEXT) {
biabl=(biabl_list*) order->DATA;
biabl->CNDABL=NULL;
biabl->VALABL=NULL;
biabl->USER =NULL;
beh_frebiabl(biabl);
}
freechain(permutations_biabl);
}
freechain(permute);
/*free mem*/
for (chain=swap_biabl; chain; chain=chain->NEXT) {
freechain(chain->DATA);
}
freechain(swap_biabl);
/*free mem*/
for (chain=mem_permutations; chain; chain=chain->NEXT) {
permutations_cnd=chain->DATA;
for (order=permutations_cnd; order; order=order->NEXT) {
freeablexpr(order->DATA);
}
freechain(permutations_cnd);
}
freechain(mem_permutations);
return head_biabl_chain;
}
/******************************************************************************/
/* return the list of different biabl resulting of permutations */
/******************************************************************************/
extern chain_list* different_biabl(befig_list* befig, biabl_list* biabl)
{
/*get all permutations possible*/
return permutations_biabl(biabl);
}

View File

@ -0,0 +1,75 @@
/*
* 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 : BooG - 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
/******************************************************************************/
/* duplicate a list */
/******************************************************************************/
extern chain_list* dupchain __P ((chain_list* chain));
/******************************************************************************/
/* return a list of list of elements */
/*which compose all the possible different orders of elem_chain */
/* elements aren't duplicated */
/******************************************************************************/
extern chain_list *swapchain __P ((chain_list* elem_chain));
/******************************************************************************/
/*parameter is a list of element list: for a place of the final list, several */
/*elements are possible */
/* return a list of element chain based on all choices proposed in parameter */
/******************************************************************************/
extern chain_list* composechain __P ((chain_list* leaves_list));
/******************************************************************************/
/* return the list of different abl resulting of permutations */
/******************************************************************************/
extern chain_list* different_abl __P ((befig_list* befig, chain_list* abl));
/******************************************************************************/
/* return the list of different biabl resulting of permutations */
/******************************************************************************/
extern chain_list* different_biabl __P ((befig_list* befig, biabl_list* biabl));
#endif

View File

@ -0,0 +1,404 @@
/*
* 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 : BooG - 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 "bog_normalize_register.h"
#include "bog_normalize_ARITY.h"
#include "bog_normalize_DAG.h"
#include "bog_normalize_simplify.h"
#include "bog_normalize_power.h"
#include "bog_lib_utils.h"
#include "bog_lib_cell.h"
#include "bog_lib_negativ.h"
#include "bog_lib_format.h"
#include "bog_lib_permute.h"
#include "bog_lib_specifications.h"
#include "bog_lib_matching.h"
#include "bog_map_pattern.h"
#include "bog_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;
}
/******************************************************************************/
/* for each aspect of abl, build a cell */
/* return 1 if included in library */
/******************************************************************************/
static int distribCell(befig_list* befig)
{
chain_list *permutations=NULL;
chain_list *chain;
cell_list *cells_lib, *cell, *pred;
char *old_cell;
biabl_list *biabl_befig, *biabl_cell, *biabl;
/*register*/
if (befig->BEREG) {
for (biabl_befig=befig->BEREG->BIABL; biabl_befig; biabl_befig=biabl_befig->NEXT) {
if ( internal_reference(befig,NULL,biabl_befig->VALABL) ) return 0;
if ( internal_reference(befig,NULL,biabl_befig->CNDABL) ) return 0;
/*in negativ logic, propagate NOT*/
biabl_befig->CNDABL=inv_oper(biabl_befig->CNDABL,0);
biabl_befig->VALABL=inv_oper(biabl_befig->VALABL,0);
/*minmize number of NOT*/
biabl_befig->CNDABL=build_negativ(biabl_befig->CNDABL);
biabl_befig->VALABL=build_negativ(biabl_befig->VALABL);
}
cells_lib=getcell_register_lib();
/*check the use of inserting this cell*/
for (cell=cells_lib; cell; cell=cell->NEXT) {
/*new match a cell description?*/
biabl_befig=befig->BEREG->BIABL;
for (biabl_cell=cell->BIABL; biabl_cell; biabl_cell=biabl_cell->NEXT)
{
if (!biabl_befig
|| !pattern_matching(biabl_befig->CNDABL,biabl_cell->CNDABL)
|| !pattern_matching(biabl_befig->VALABL,biabl_cell->VALABL)) break;
biabl_befig=biabl_befig->NEXT;
}
/*not the good cell to compare*/
if (biabl_cell) continue;
/* patterns are equal? */
biabl_cell=cell->BIABL;
for (biabl_befig=befig->BEREG->BIABL; biabl_befig; biabl_befig=biabl_befig->NEXT)
{
if (!biabl_cell
|| !pattern_matching(biabl_cell->CNDABL,biabl_befig->CNDABL)
|| !pattern_matching(biabl_cell->VALABL,biabl_befig->VALABL)) break;
biabl_cell=biabl_cell->NEXT;
}
/*patterns aren't equal, new is more precise*/
if (!biabl_befig) break;
/*patterns are equal -->comparison*/
if (cell->AREA<getgenericarea(befig)) return 0; /*don't use the new*/
if (cell->AREA==getgenericarea(befig)) break; /*insert new*/
/*remove old cells because they are bigger*/
fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",cell->NAME);
old_cell=cell->NAME;
pred=NULL;
for (cell=cells_lib ; cell; cell=cell->NEXT) {
if (cell->NAME==old_cell && pred) pred->NEXT=cell->NEXT;
else if (cell->NAME==old_cell) cells_lib=cell->NEXT;
else pred=cell;
}
setcell_register_lib(cells_lib);
break; /*insert new*/
}
/*give the list of different permutations*/
permutations=different_biabl(befig,befig->BEREG->BIABL);
/*put in cell*/
for (chain=permutations; chain; chain=chain->NEXT) {
biabl= (biabl_list*) chain->DATA;
addCell_register(befig, biabl);
}
}
/*bus*/
else if (befig->BEBUS) {
for (biabl_befig=befig->BEBUS->BIABL; biabl_befig; biabl_befig=biabl_befig->NEXT) {
/*in negativ logic, propagate NOT*/
biabl_befig->CNDABL=inv_oper(biabl_befig->CNDABL,0);
biabl_befig->VALABL=inv_oper(biabl_befig->VALABL,0);
/*minmize number of NOT*/
biabl_befig->CNDABL=build_negativ(biabl_befig->CNDABL);
biabl_befig->VALABL=build_negativ(biabl_befig->VALABL);
}
cells_lib=getcell_tristate_lib();
/*check the use of inserting this cell*/
for (cell=cells_lib; cell; cell=cell->NEXT) {
/*new match a cell description?*/
biabl_befig=befig->BEBUS->BIABL;
for (biabl_cell=cell->BIABL; biabl_cell; biabl_cell=biabl_cell->NEXT)
{
if (!biabl_befig
|| !pattern_matching(biabl_befig->CNDABL,biabl_cell->CNDABL)
|| !pattern_matching(biabl_befig->VALABL,biabl_cell->VALABL)) break;
biabl_befig=biabl_befig->NEXT;
}
/*not the good cell to compare*/
if (biabl_cell) continue;
/* patterns are equal? */
biabl_cell=cell->BIABL;
for (biabl_befig=befig->BEBUS->BIABL; biabl_befig; biabl_befig=biabl_befig->NEXT)
{
if (!biabl_cell
|| !pattern_matching(biabl_cell->CNDABL,biabl_befig->CNDABL)
|| !pattern_matching(biabl_cell->VALABL,biabl_befig->VALABL)) break;
biabl_cell=biabl_cell->NEXT;
}
/*patterns aren't equal, new is more precise*/
if (!biabl_befig) break;
/*patterns are equal -->comparison*/
if (cell->AREA<getgenericarea(befig)) return 0; /*don't use the new*/
if (cell->AREA==getgenericarea(befig)) break; /*insert new*/
/*remove old cells because they are bigger*/
fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",cell->NAME);
old_cell=cell->NAME;
pred=NULL;
for (cell=cells_lib ; cell; cell=cell->NEXT) {
if (cell->NAME==old_cell && pred) pred->NEXT=cell->NEXT;
else if (cell->NAME==old_cell) cells_lib=cell->NEXT;
else pred=cell;
}
setcell_tristate_lib(cells_lib);
break; /*insert new*/
}
/*give the list of different permutations*/
permutations=different_biabl(befig,befig->BEBUS->BIABL);
/*put in cell*/
for (chain=permutations; chain; chain=chain->NEXT) {
biabl= (biabl_list*) chain->DATA;
addCell_bus(befig, biabl);
}
}
/*logic*/
else if (befig->BEOUT) {/*pure logical*/
/*in negativ logic, propagate NOT*/
befig->BEOUT->ABL=inv_oper(befig->BEOUT->ABL,0);
/*minmize number of NOT*/
befig->BEOUT->ABL=build_negativ(befig->BEOUT->ABL);
cells_lib=getcell_logic_lib();
/*check the use to insert this cell*/
for (cell=cells_lib; cell; cell=cell->NEXT) {
/*new more precise than old -> put new before*/
if (pattern_matching(befig->BEOUT->ABL,cell->ABL)) {
/*patterns are equal*/
if (pattern_matching(cell->ABL,befig->BEOUT->ABL)) {
if (cell->AREA<getgenericarea(befig)) return 0;
if (cell->AREA==getgenericarea(befig)) break; /*insert new*/
/*remove old cells because they are bigger*/
fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",cell->NAME);
old_cell=cell->NAME;
pred=NULL;
for (cell=cells_lib ; cell; cell=cell->NEXT) {
if (cell->NAME==old_cell && pred) pred->NEXT=cell->NEXT;
else if (cell->NAME==old_cell) cells_lib=cell->NEXT;
else pred=cell;
}
setcell_logic_lib(cells_lib);
}
/*insert new*/
break;
}
}
/*give the list of different permutations*/
permutations=different_abl(befig,befig->BEOUT->ABL);
for (chain=permutations; chain; chain=chain->NEXT) {
/*several abl for a same behavior!!! ex: and(or ...) == nor(nor...)*/
addCell_logic(befig, chain->DATA);
}
}
if (permutations) freechain(permutations);
return 1;
}
/*****************************************************************************/
/* 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");
/*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;
if (!vbe_list /*list of name*/) {
fprintf(stderr,
"Mapping Error: no cell in directory '%s'\n",
cell_directory?cell_directory:".");
exit(1);
}
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,'P');
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 -needed by format_register()- */
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;
}
/*put arity oper*/
put_arity(befig);
/*memorize cell if not already exists*/
if (!distribCell(befig)) {
fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",befig->NAME);
}
}
freechain(vbe_list);
/*relax old env*/
WORK_LIB=memo_work;
CATA_LIB=memo_cata;
}

View File

@ -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 : BooG - 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

View File

@ -0,0 +1,549 @@
/*
* 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 : BooG - cell properties
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <mlo.h>
#include <abl.h>
#include <abe.h>
#include "bog_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 or rup_i */
#define Rup "rup"
#endif
#ifndef Rdown /* rdown_i_t or rdown_i */
#define Rdown "rdown"
#endif
/*for inputs to output: Tphl_i_t or Tphl_i */
#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 or tsr_i */
#define Tsr "tsr"
#endif
#ifndef Tsf /* tsf_i_ck or tsf_i */
#define Tsf "tsf"
#endif
#ifndef Thr /* thr_i_ck or thr_i */
#define Thr "thr"
#endif
#ifndef Thf /* thf_i_ck*/
#define Thf "thf"
#endif
#ifndef Tar /* tar_ck_q or tar_ck */
#define Tar "tar"
#endif
#ifndef Taf /* taf_ck_q or taf_ck */
#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 float getgenericT(befig_list* befig, char* name)
{
begen_list* begen;
char* Thl, *Tll, *Tlh, *Thh, *tar, *taf;
char* Thl_o, *Tll_o, *Tlh_o, *Thh_o, *tar_o, *taf_o;
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_o=concatname(Thl,output);
Tll_o=concatname(Tll,output);
Thh_o=concatname(Thh,output);
Tlh_o=concatname(Tlh,output);
tar_o=concatname(tar,output);
taf_o=concatname(taf,output);
SEPAR=memo;
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
if (begen->NAME==Thl_o || begen->NAME==Thh_o || begen->NAME==Tlh_o
|| begen->NAME==Tll_o || begen->NAME==tar_o || begen->NAME==taf_o
|| 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 (float) T_setup/count;
}
/******************************************************************************/
/* return the setup in high value of an entry in pico second */
/******************************************************************************/
extern float getgenericTh(befig_list* befig, char* name)
{
begen_list* begen;
char *Tlh, *Thh;
char *Tlh_o, *Thh_o;
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_o=concatname(Thh,output);
Tlh_o=concatname(Tlh,output);
SEPAR=memo;
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
if (begen->NAME==Thh || begen->NAME==Tlh
|| begen->NAME==Thh_o || begen->NAME==Tlh_o) {
T_setup+=getvalue(begen);
count++;
}
}
if (count==0) return 0;
return (float) T_setup/count;
}
/******************************************************************************/
/* return the setup in low value of an entry in pico second */
/******************************************************************************/
extern float getgenericTl(befig_list* befig, char* name)
{
begen_list* begen;
char* Thl, *Tll;
char* Thl_o, *Tll_o;
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_o=concatname(Thl,output);
Tll_o=concatname(Tll,output);
SEPAR=memo;
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
if (begen->NAME==Thl_o || begen->NAME==Tll_o
|| begen->NAME==Thl || begen->NAME==Tll) {
T_setup+=getvalue(begen);
count++;
}
}
if (count==0) return 0;
return (float) T_setup/count;
}
/******************************************************************************/
/* set the setup Times of an entry in pico second (exp-12) */
/******************************************************************************/
extern void putgenericT(befig_list* befig, char* name, float Thl_value, float Tll_value, float Tlh_value, float 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 float 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 (float)getvalue(begen)/1000;
}
return 0;
}
/******************************************************************************/
/* set the Capacitance of an entry in pico Farad */
/******************************************************************************/
extern void putgenericC(befig_list* befig, char* name, float 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;
char* R_up_o, *R_down_o;
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_o=concatname(R_up,output);
R_down_o=concatname(R_down,output);
SEPAR=memo;
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
if (begen->NAME==R_up || begen->NAME==R_down
|| begen->NAME==R_up_o || begen->NAME==R_down_o) {
R+=getvalue(begen);
count++;
}
}
if (count==0) return 0;
return (float) R/count;
}
/******************************************************************************/
/* set Resistivity in Ohm of path from input to output cell */
/******************************************************************************/
extern void putgenericR(befig_list* befig, char* name, float Rup_value, float 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, *R_up_o;
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_o=concatname(R_up,output);
SEPAR=memo;
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
if (begen->NAME==R_up || begen->NAME==R_up_o) {
R+=getvalue(begen);
count++;
}
}
if (count==0) return 0;
return (float) 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, *R_down_o;
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_o=concatname(R_down,output);
SEPAR=memo;
for (begen=befig->BEGEN; begen; begen=begen->NEXT) {
if (begen->NAME==R_down || begen->NAME==R_down_o) {
R+=getvalue(begen);
count++;
}
}
if (count==0) return 0;
return (float) 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 (float)C/count/1000; /* femto Farad (exp-15) -> pico Farad (exp-12)*/
}

View File

@ -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 : BooG - 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 float getgenericT __P ((befig_list* befig, char* name));
/******************************************************************************/
/* return the setup in high value of an entry in pico second */
/******************************************************************************/
extern float getgenericTh __P ((befig_list* befig, char* name));
/******************************************************************************/
/* return the setup in low value of an entry in pico second */
/******************************************************************************/
extern float 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, float Thl_value, float Tll_value, float Tlh_value, float Thh_value));
/******************************************************************************/
/* return the Capacitance of an entry in pico Farad (exp-12) */
/******************************************************************************/
extern float 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, float 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, float Rup_value, float Rdown_value));
/******************************************************************************/
/* return the average of Capacitance of all inputs in pico Farad */
/******************************************************************************/
extern int getaverageC __P ((befig_list* befig));
#endif

View File

@ -0,0 +1,248 @@
/*
* 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 : BooG - library cells utilities
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <mlo.h>
#include <abl.h>
#include <abe.h>
#include "bog_lax_param.h"
#include "bog_lib_matching.h"
#include "bog_lib_specifications.h"
#include "bog_lib_utils.h"
/*size of memory block*/
#define BLOCK 512
static port_list* PORT;
/***************************************************************************/
/* return a new port taken from the heap */
/***************************************************************************/
extern 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->ABL=NULL;
new->C=0;
new->R=0;
new->T=0;
new->DIRECTION=0;
new->STABLE =0;
new->NEGATIV=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->ABL=head->ABL;
new->C=head->C;
new->R=head->R;
new->T=head->T;
new->DIRECTION=head->DIRECTION;
new->STABLE =head->STABLE;
new->NEGATIV=head->NEGATIV;
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->ABL=head->ABL;
new->C=head->C;
new->R=head->R;
new->T=head->T;
new->DIRECTION=head->DIRECTION;
new->STABLE =head->STABLE;
new->NEGATIV=head->NEGATIV;
new->NAME=head->NAME;
}
/******************************************************************************/
/*build a new cell in our library */
/* port of cell is the inverted list of bepor */
/******************************************************************************/
extern cell_list* addCell(befig_list* befig)
{
cell_list* cell;
port_list* new;
bepor_list* bepor;
cell=(cell_list*) mbkalloc(sizeof(cell_list));
cell->NAME=befig->NAME;
cell->DELAY=0;
cell->MODE='P'; /*cell won't be developped in lofig result*/
cell->AREA=getgenericarea(befig);
cell->ABL=NULL;
cell->BIABL=NULL;
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;
new->DIRECTION=bepor->DIRECTION;
/*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;
}
/******************************************************************************/
/*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->MODE=old->MODE;
cell->AREA=old->AREA;
cell->ABL=old->ABL;
cell->BIABL=old->BIABL;
cell->PORT=old->PORT;
cell->NEXT=old->NEXT;
return cell;
}
/******************************************************************************/
/*insert a new cell in a list of cells */
/* the sort is the biggest to the lowest cell */
/* (AND a b) is after (AND a (NOT b)) */
/* because is always better to take the biggest cell to match for example: */
/* (AND (NOT a) (NOT b)) will be matched by (AND a (NOT b)) */
/*return the new list if inserted else return NULL */
/******************************************************************************/
extern cell_list* classCell(cell_list* new, cell_list* list)
{
cell_list* cell, *pred=NULL;
biabl_list *biabl_new, *biabl_cell;
for (cell=list; cell; cell=cell->NEXT) {
/*new more precise than old -> put new before*/
if (new->BIABL) {
biabl_cell=cell->BIABL;
for (biabl_new=new->BIABL; biabl_cell && biabl_new; biabl_new=biabl_new->NEXT) {
if (pattern_matching(biabl_new->CNDABL,biabl_cell->CNDABL)
&& pattern_matching(biabl_new->VALABL,biabl_cell->VALABL)) break;
biabl_cell=biabl_cell->NEXT;
}
if (biabl_new) break; /*insert cell here*/
}
else {
if (pattern_matching(new->ABL,cell->ABL)) break; /*insert cell here*/
}
pred=cell;
}
new->NEXT=cell;
/*new is at the beginning*/
if (!pred) return new;
/*new is placed inside list*/
pred->NEXT=new;
return list;
}

View File

@ -0,0 +1,116 @@
/*
* 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 : BooG - 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*/
float T; /* (Tphh+Tpll+Tplh+Tphl)/4 in ps */
float C; /* Cin in pF */
float R; /* Rout in Ohm */
chain_list* ABL; /* abl of leaf for mapping*/
int STABLE; /*non-zero if pointed by a STABLE expr in abl*/
int DIRECTION; /* VDD(char*),VSS, IN(const),OUT,INOUT,TRISTATE,TRANSCV*/
int NEGATIV; /*flag set to show if ABL field must be inverted or not*/
} port_list;
/*image of a befig from the cell library*/
typedef struct cell {
struct cell* NEXT;
port_list* PORT; /*image of bepor*/
chain_list* ABL; /*it isn't an abl, it's leaves point on port element*/
biabl_list* BIABL; /*for cell with condition block*/
char* NAME; /*name of befig*/
int AREA;
befig_list* BEFIG; /*befig represented*/
char MODE; /*if 'A' (all), cell is developped in lofig*/
/*if 'P' (partial), it's known only as a loins name*/
float DELAY; /*to memorize a temporary delay on a cell*/
} cell_list;
/***************************************************************************/
/* return a new port taken from the heap */
/***************************************************************************/
extern port_list* newport __P (());
/******************************************************************************/
/*build a new cell in our library */
/* port of cell is the inverted list of bepor */
/******************************************************************************/
extern cell_list* 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));
/******************************************************************************/
/*insert a new cell in a list of cells */
/* the sort is the biggest to the lowest cell */
/* (AND a b) is after (AND a (NOT b)) */
/* because is always better to take the biggest cell to match for example: */
/* (AND (NOT a) (NOT b)) will be matched by (AND a (NOT b)) */
/*return the new list if inserted else return NULL */
/******************************************************************************/
extern cell_list* classCell __P ((cell_list* new_cell, cell_list* list));
/******************************************************************************/
/*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));
#endif

View File

@ -0,0 +1,456 @@
/*
* 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 : BooG Binding and optimizing on gates
* 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 "bog_lax_param.h"
#include "bog_normalize_DAG.h"
#include "bog_normalize_register.h"
#include "bog_normalize_DC.h"
#include "bog_normalize_power.h"
#include "bog_normalize_nameindex.h"
#include "bog_normalize_simplify.h"
#include "bog_normalize_ARITY.h"
#include "bog_signal_nameindex.h"
#include "bog_signal_delay.h"
#include "bog_map_abl.h"
#include "bog_map_befig.h"
#include "bog_map_delay.h"
#include "bog_unflatten_befig.h"
#include "bog_lib_reader.h"
#include "bog_lib_utils.h"
#include "bog_lib_cell.h"
#include "bog_lib_complete.h"
#include "bog_signal_utils.h"
#include "bog_signal_adapt.h"
#include "bog_xsch_driver.h"
#ifndef BOOG
#define BOOG "boog"
#endif
#define USAGE "\
usage: "BOOG" <input_file> <output_file> [<lax_file>]\n\
"
/*usage with options*/
#define OPT_USAGE USAGE "\
"BOOG" -h\n\
"BOOG" <input_file> [-o <output_file>] [-l <lax_file>] [-x <xsch_mode>] [-m <optim_mode>]\n\
"BOOG" <input_file> -d <debug_file>\n\
"
#define HELP_USAGE OPT_USAGE "\n\
\t-h Displays this help page.\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> VBE input file name.\n\
\t-o <output_file> VST output file name.\n\
\t-l <lax_file> LAX parameter file name. See lax(1) for more info.\n\
\t-d <debug_file> VBE debug file name. Users aren't concerned.\n\
"
/*options*/
#define DEBUG_FILE 'd'
#define OUTPUT_FILE 'o'
#define LAX_FILE 'l'
#define HELP_MODE 'h'
#define OPTIM_MODE 'm'
#define XSCH_MODE 'x'
/*options variables*/
extern char *optarg;
static int verbose_mode=0, optim_mode=DEFAULT_OPTIM, xsch_mode=XSCH_CRITICAL_PATH;
static char *input_file=NULL, *output_file=NULL, *lax_file=NULL, *debug_file=NULL, *xsch_file=NULL;
/*alliance env*/
static char* TARGET_LIB;
/******************************************************************************/
/* 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,"-d:l:o:m:x:h")) != EOF) {
switch (opt) {
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 DEBUG_FILE:
if (!debug_file) {debug_file=optarg; break;}
fprintf(stderr,OPT_USAGE "\n");
exit(1);
case OUTPUT_FILE:
if (!output_file) {output_file=optarg; 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],"-h")) {fprintf(stdout,HELP_USAGE "\n"); exit(0);}
/*take option and argument*/
if (!strcmp(argv[i],"-o")) {
if (++i<argc) {output_file=argv[i]; continue;}
fprintf(stderr,OPT_USAGE "\n");
exit(1);
}
if (!strcmp(argv[i],"-l")) {
if (++i<argc) {lax_file=argv[i]; continue;}
fprintf(stderr,OPT_USAGE "\n");
exit(1);
}
if (!strcmp(argv[i],"-d")) {
if (++i<argc) {debug_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")) continue;
/*skip option and argument*/
if (!strcmp(argv[i],"-x") || !strcmp(argv[i],"-o") || !strcmp(argv[i],"-d")
|| !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);
}
/*coherence in options*/
if (!input_file) {
fprintf(stderr,OPT_USAGE "\n");
exit(1);
}
if (debug_file && !strcmp(debug_file,input_file)) {
fprintf(stderr,"A different <debug_file> is needed for option '-%c'\n",DEBUG_FILE);
fprintf(stderr,OPT_USAGE "\n");
exit(1);
}
/*take default values*/
if (!output_file) output_file=input_file;
xsch_file=output_file;
verbose_mode=1;
}
/******************************************************************************/
/* main BOOG */
/******************************************************************************/
extern int main (int argc, char* argv[])
{
lofig_list *lofig;
befig_list *befig;
ptype_list *long_path=NULL;
/*init*/
mbkenv(); /*mbk*/
ablenv(); /*abl*/
autenv(); /*hash table*/
bddenv(); /*for vhdlloadbefig() */
alliancebanner_with_authors("BooG", VERSION " [2002/02/11]", "Binding and Optimizing On Gates",
"2000", "5.0"/*ALLIANCE_VERSION*/, "François Donnet");
/*alliance env: extension netlist file (vst or al)*/
fprintf(stdout," MBK_VDD : %s\n",VDD);
fprintf(stdout," MBK_VSS : %s\n",VSS);
fprintf(stdout," MBK_IN_LO : %s\n",IN_LO);
fprintf(stdout," MBK_OUT_LO : %s\n",OUT_LO);
fprintf(stdout," MBK_WORK_LIB : %s\n",WORK_LIB);
/*if no library defined*/
TARGET_LIB=mbkgetenv("MBK_TARGET_LIB");
if (TARGET_LIB)
fprintf(stdout," MBK_TARGET_LIB : %s\n",TARGET_LIB);
else {
fprintf(stderr,
"Environment Error: no 'MBK_TARGET_LIB' defined for cells directory\n");
exit(1);
}
/*set options*/
set_param(argc,argv);
/*separ*/
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 vbe and keep internal signals in befig*/
fprintf(stdout,"Reading file '%s.vbe'...\n",input_file);
befig=vhdlloadbefig(NULL, input_file, 2/*BVL_KEEPAUX*/);
if (befig->ERRFLG) {
fprintf(stderr,"BEH: error %d unknown in '%s.vbe'\n",
befig->ERRFLG, input_file);
exit(1);
}
/*check coherence between LAX and befig*/
if (lax_file) {
fprintf(stdout,"Controlling file '%s.lax'...\n",lax_file);
if (!coherencelax(befig)) exit(1);
}
/*check file error not detected by parser*/
fprintf(stdout,"Controlling file '%s.vbe'...\n",input_file);
/*detect power and forbid Vdd and Vss in expression*/
if (!detect_power(befig)) exit(1);
/*remove don't care and 'z' -simplify_expr() will be better-*/
remove_DC(befig);
/*simplify abl expression -needed by format_register()- */
simplify_expr(befig);
/*remove stable -needed by DAG_control()- */
if (!format_register(befig)) exit(1);
/*control cycles in befig and erase unused bebux and beaux*/
if (!DAG_control(befig)) exit(1);
/*read cell library*/
fprintf(stdout,"Reading lib '%s'...\n",TARGET_LIB);
library_reader(TARGET_LIB);
/*control cell library and complete if we can*/
fprintf(stdout,"Controlling lib '%s'...\n",TARGET_LIB);
control_lib();
/*all work to map without any problem*/
fprintf(stdout,"Preparing file '%s.vbe'...\n",input_file);
change_radical(befig);/*to avoid conflict with names -we need control_lib()*/
/*put arity operator*/
put_arity(befig);
/*choose now the place of big cell, and adapt polarity of abl*/
/*eval C for each signal: it is a sum of all sortance cell capacitance*/
fprintf(stdout,"Capacitances on file '%s.vbe'...\n",input_file);
adapt_for_cell(befig);
/*divide the arity of big operator with optimization in area or time*/
fprintf(stdout,"Unflattening file '%s.vbe'...\n",input_file);
unflatten_befig(befig);
/*remove some unused beaux procuced by unflattening*/
if (!DAG_control(befig)) exit(1);
/*mapping of cells*/
fprintf(stdout,"Mapping file '%s.vbe'...\n",input_file);
lofig=map_befig(befig,output_file);
/*free memory of last treatment*/
free_nameindex();
/*saving file*/
if (output_file) {
fprintf(stdout,"Saving file '%s.%s'...\n",output_file,OUT_LO);
savelofig(lofig); /*change la lofigchain en mode .al*/
lofigchain(lofig);
}
if (verbose_mode) {
ptype_list *loins_num, *ptype, *pred;
char* max_input=NULL, *max_output=NULL;
int all=0;
long delay;
bereg_list* bereg;
/*eval delay*/
fprintf(stdout,"Quick estimated critical path (no warranty)...");
fflush(stdout);
long_path=max_delay_path(befig,lofig); /*sig which obtains the latest value*/
if (long_path) {
max_input=(char*) long_path->DATA;
/*search last*/
pred=NULL;
for (ptype=long_path; ptype->NEXT; ptype=ptype->NEXT) pred=ptype;
max_output=(char*) ptype->DATA;
delay=ptype->TYPE;
fprintf(stdout,"%ld ps from '%s' to '%s'\n", delay, max_input, max_output);
/*remove last if register, because it doesn't belong to critical path*/
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
if (bereg->NAME==max_output && pred) {
pred->NEXT=NULL;
freeptype(ptype);
}
}
}
else fprintf(stdout,"no output!\n");
/*eval area*/
fprintf(stdout,"Quick estimated area (with over-cell routing)...%d lambda²\n",
count_area());
/*be more precise*/
loins_num=count_instance(lofig);
if (!loins_num) fprintf(stdout,"No instance...\n");
else {
fprintf(stdout,"Details...\n");
for (ptype=loins_num; ptype; ptype=ptype->NEXT) {
fprintf(stdout,"\t%s: %ld\n",(char*)ptype->DATA,ptype->TYPE);
all+=ptype->TYPE;
}
fprintf(stdout,"\tTotal: %d\n",all);
}
freeptype(loins_num);
}
/*colors and weight informations for xsch alliance displayer*/
if (xsch_file) {
FILE* xsch_stream;
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);
}
save_xsch(xsch_stream,lofig,long_path,xsch_mode);
fclose(xsch_stream);
}
/*for debugging extract a resulting vbe file to compare with source*/
if (debug_file) {
fprintf(stdout,"Formating debug file '%s.vbe'...\n",debug_file);
put_back_STABLE(befig); /*put in condition register STABLE*/
normalize_nameindex(befig); /*for bits of vectors*/
sort_vector(befig); /*needed to be recognized by parser/driver */
binary_oper(befig); /*to accept NXOR, NOR, NAND */
befig->NAME=debug_file; /* no namealloc() not to change in lower letter*/
fprintf(stdout,"Saving debug file '%s.vbe'...\n",debug_file);
vhdlsavebefig(befig,0);
}
fprintf(stdout,"End of %s...\n\n",BOOG);
exit(0);
}

View File

@ -0,0 +1,422 @@
/*
* 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 : BooG - mapping standard cells on abl
* Date : 2000
* Author : Francois Donnet
*/
#include <stdlib.h>
#include <stdio.h>
#include <mut.h>
#include <mlo.h>
#include <mlu.h>
#include <abl.h>
#include <abe.h>
#include "bog_lib_utils.h"
#include "bog_signal_utils.h"
#include "bog_signal_nameindex.h"
#include "bog_map_pattern.h"
#include "bog_map_befig.h"
#include "bog_map_abl.h"
static unsigned int AREA; /*sum of cells area*/
/******************************************************************************/
/* initialize area evaluation */
/******************************************************************************/
extern void begin_count_area()
{
AREA=0;
}
/******************************************************************************/
/* return area evaluation */
/******************************************************************************/
extern unsigned int count_area()
{
return AREA;
}
/******************************************************************************/
/* add references to losig for instance loins */
/******************************************************************************/
static void addlofigchain(loins_list* loins)
{
locon_list *ptcon;
losig_list *ptsig;
ptype_list *ptype;
for (ptcon=loins->LOCON; ptcon; ptcon=ptcon->NEXT) {
ptsig=ptcon->SIG;
ptype = getptype(ptsig->USER, LOFIGCHAIN);
if (!ptype) {
ptsig->USER=addptype(ptsig->USER,LOFIGCHAIN,NULL);
ptype=ptsig->USER;
}
ptype->DATA = addchain((chain_list *)ptype->DATA, ptcon);
}
}
/****************************************************************************/
/* build loins and its connections in lofig according to abl */
/* output is the signal of the variable which the abl defines */
/****************************************************************************/
static losig_list* loc_map_abl(lofig_list *lofig, chain_list *abl)
{
losig_list* losig;
port_list* port, *top;
chain_list* sigchain = NULL, *new, *pred=NULL;
char* insname;
chain_list* namechain;
cell_list* cell;
losig_list* output_losig;
loins_list* loins;
int master;
if (!abl || !lofig) {
fprintf(stderr,"loc_map_abl: NULL pointer\n");
exit(1);
}
/*constants are considered as signal names*/
if (ABL_ATOM(abl)) return seeksignal(ABL_ATOM_VALUE(abl));
/*first recursion?*/
master=first_eval();
/*map operator*/
/*cell->PORT contains the result of pattern matching*/
cell=cell_pattern(abl);
insname=getnameindex(cell->NAME);
putdelay(loins_name(insname),cell->DELAY); /*delay for loins*/
putdelay(insname,cell->DELAY); /*delay for new signal*/
/*output_losig */
namechain=addchain(NULL,insname);
output_losig=addlosig(lofig, getindex(), namechain, INTERNAL);
top=copyport(cell->PORT); /*not to be disturb by recursion*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME)) losig=seeksignal(VSS);
else if (isvdd(port->NAME)) losig=seeksignal(VDD);
else switch (port->DIRECTION) {
case OUT: case TRISTATE: losig=output_losig; break;
default:
if (!port->ABL) {
fprintf(stderr,
"loc_map_abl: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
losig=loc_map_abl(lofig,port->ABL);
break;
}
new=addchain(NULL,losig);
if (pred) pred->NEXT=new;
else sigchain=new;
pred=new;
}
/*insert instance*/
loins=addloins(lofig,insname,getlofig(cell->NAME,'P'),sigchain);
addlofigchain(loins);
freechain(sigchain);
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
/*if cell doesn't exist but is composed by several cells, develop it*/
if (cell->MODE=='A' || cell->MODE=='a') {
flattenlofig(lofig,insname,YES/*change internal signal name*/);
}
AREA+=cell->AREA;
return output_losig;
}
/****************************************************************************/
/* build loins and its connections in lofig according to abl */
/* output is the signal of the variable which the abl defines */
/****************************************************************************/
extern void map_abl(lofig_list *lofig, chain_list *abl, losig_list *output_losig)
{
losig_list* losig;
loins_list* loins;
port_list* port, *top;
chain_list* sigchain = NULL, *new, *pred=NULL;
char* insname;
cell_list* cell;
int master;
if (!abl || !lofig) {
fprintf(stderr,"map_abl: NULL pointer\n");
exit(1);
}
if (!output_losig) {
fprintf(stderr,"map_abl: no losig for output\n");
exit(1);
}
/*first recursion?*/
master=first_eval();
/*search buffer, one or zero constant*/
cell=cell_pattern(abl);
insname=(char*)output_losig->NAMECHAIN->DATA;
putdelay(loins_name(insname),cell->DELAY); /*delay for loins*/
top=copyport(cell->PORT); /*not to be disturb by recursion*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME)) losig=seeksignal(VSS);
else if (isvdd(port->NAME)) losig=seeksignal(VDD);
else switch (port->DIRECTION) {
case OUT: case TRISTATE: losig=output_losig; break;
default:
if (!port->ABL) {
fprintf(stderr,
"map_abl: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
losig=loc_map_abl(lofig,port->ABL);
}
new=addchain(NULL,losig);
if (pred) pred->NEXT=new;
else sigchain=new;
pred=new;
}
loins=addloins(lofig,insname,getlofig(cell->NAME,'P'),sigchain);
addlofigchain(loins);
freechain(sigchain);
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
/*if cell doesn't exist but is composed by several cells, develop it*/
if (cell->MODE=='A' || cell->MODE=='a') {
flattenlofig(lofig,insname,YES/*change internal signal name*/);
}
AREA+=cell->AREA;
}
/******************************************************************************/
/* map a tristate */
/******************************************************************************/
extern void map_bus(lofig_list* lofig, biabl_list* biabl, losig_list* output_losig)
{
losig_list* losig;
loins_list* loins;
chain_list* sigchain = NULL, *new, *pred=NULL;
char* insname;
port_list* port, *top;
cell_list* cell;
char memo;
int master;
biabl_list* biabl_aux;
if (!biabl || !lofig) {
fprintf(stderr,"map_bus: NULL pointer\n");
exit(1);
}
if (!output_losig) {
fprintf(stderr,"map_bus: no losig for output\n");
exit(1);
}
/*first recursion?*/
master=first_eval();
/*cell->PORT contains the result of pattern matching*/
cell=cell_pattern_bus(biabl);
insname=biabl->LABEL;
/*skip conditions matched by cell*/
for (biabl_aux=cell->BIABL; biabl_aux; biabl_aux=biabl_aux->NEXT)
biabl=biabl->NEXT;
/*give unique name*/
if (!biabl) insname=(char*)output_losig->NAMECHAIN->DATA;
else {
memo=SEPAR;
SEPAR='_';
insname=concatname((char*)output_losig->NAMECHAIN->DATA,insname);
SEPAR=memo;
}
putdelay(loins_name(insname),cell->DELAY); /*delay for loins*/
top=copyport(cell->PORT);
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME)) losig=seeksignal(VSS);
else if (isvdd(port->NAME)) losig=seeksignal(VDD);
else switch (port->DIRECTION) {
case OUT: case TRISTATE: losig=output_losig; break;
default:
if (!port->ABL) {
fprintf(stderr,
"map_bus: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
losig=loc_map_abl(lofig,port->ABL);
break;
}
new=addchain(NULL,losig);
if (pred) pred->NEXT=new;
else sigchain=new;
pred=new;
}
loins=addloins(lofig,insname,getlofig(cell->NAME,'P'),sigchain);
addlofigchain(loins);
freechain(sigchain);
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
/*if cell doesn't exist but is composed by several cells, develop it*/
if (cell->MODE=='A' || cell->MODE=='a') {
flattenlofig(lofig,insname,YES/*change internal signal name*/);
}
AREA+=cell->AREA;
/*look the other blocks*/
if (biabl) {
map_bus(lofig,biabl,output_losig);
}
}
/******************************************************************************/
/* map on a simple register */
/******************************************************************************/
extern void map_register(lofig_list* lofig, biabl_list* biabl, losig_list* output_losig)
{
losig_list* losig;
loins_list* loins;
chain_list* sigchain = NULL, *new, *pred=NULL;
port_list* port, *top;
char* insname;
char memo;
cell_list* cell;
int master;
biabl_list* biabl_aux;
if (!biabl || !lofig) {
fprintf(stderr,"map_register: NULL pointer\n");
exit(1);
}
if (!output_losig) {
fprintf(stderr,"map_register: no losig for output\n");
exit(1);
}
/*first recursion?*/
master=first_eval();
/*cell->PORT contains the result of pattern matching*/
cell=cell_pattern_reg(biabl);
insname=biabl->LABEL;
/*skip conditions matched by cell*/
for (biabl_aux=cell->BIABL; biabl_aux; biabl_aux=biabl_aux->NEXT)
biabl=biabl->NEXT;
/*give unique name*/
if (!biabl) insname=(char*)output_losig->NAMECHAIN->DATA;
else {
memo=SEPAR;
SEPAR='_';
insname=concatname((char*)output_losig->NAMECHAIN->DATA,insname);
SEPAR=memo;
}
putdelay(loins_name(insname),cell->DELAY); /*delay for loins*/
top=copyport(cell->PORT);
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME)) losig=seeksignal(VSS);
else if (isvdd(port->NAME)) losig=seeksignal(VDD);
else switch (port->DIRECTION) {
case OUT: case TRISTATE: losig=output_losig; break;
default:
if (!port->ABL) {
fprintf(stderr,
"map_register: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
losig=loc_map_abl(lofig,port->ABL);
break;
}
new=addchain(NULL,losig);
if (pred) pred->NEXT=new;
else sigchain=new;
pred=new;
}
loins=addloins(lofig,insname,getlofig(cell->NAME,'P'),sigchain);
addlofigchain(loins);
freechain(sigchain);
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
/*if cell doesn't exist but is composed by several cells, develop it*/
if (cell->MODE=='A' || cell->MODE=='a') {
flattenlofig(lofig,insname,YES/*change internal signal name*/);
}
AREA+=cell->AREA;
/*look the other blocks*/
if (biabl) {
map_register(lofig,biabl,output_losig);
}
}

View File

@ -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 : BooG - mapping standard cells on abl
* Date : 2000
* Author : Francois Donnet
*/
#ifndef MAP_ABL_H
#define MAP_ABL_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/******************************************************************************/
/* initialize area evaluation */
/******************************************************************************/
extern void begin_count_area __P (());
/******************************************************************************/
/* return area evaluation */
/******************************************************************************/
extern unsigned int count_area __P (());
/****************************************************************************/
/* build loins and its connections in lofig according to abl */
/* output is the signal of the variable which the abl defines */
/****************************************************************************/
extern void map_abl __P ((lofig_list *lofig, chain_list *abl, losig_list *output));
/******************************************************************************/
/* map a tristate */
/******************************************************************************/
extern void map_bus __P ((lofig_list* lofig, biabl_list* biabl, losig_list* output_losig));
/******************************************************************************/
/* map on a simple register */
/******************************************************************************/
extern void map_register __P ((lofig_list* lofig, biabl_list* biabl, losig_list* output_losig));
#endif

View File

@ -0,0 +1,397 @@
/*
* 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 : BooG - evaluate Capacitance
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <mlo.h>
#include <abl.h>
#include <abe.h>
#include "bog_lib_utils.h"
#include "bog_lib_negativ.h"
#include "bog_lib_cell.h"
#include "bog_signal_utils.h"
#include "bog_signal_nameindex.h"
#include "bog_normalize_message.h"
#include "bog_normalize_ARITY.h"
#include "bog_map_prepare.h"
#include "bog_map_adapt.h"
/******************************************************************************/
/* swap the contain of 2 abl */
/******************************************************************************/
extern void swap_pointers(chain_list* abl1, chain_list* abl2)
{
chain_list* cdr, *car;
car=ABL_CAR(abl1);
cdr=ABL_CDR(abl1);
ABL_CAR(abl1)=ABL_CAR(abl2);
ABL_CDR(abl1)=ABL_CDR(abl2);
ABL_CAR(abl2)=car;
ABL_CDR(abl2)=cdr;
}
/******************************************************************************/
/* invert abl of port whose NEGATIV flag is set */
/******************************************************************************/
extern void invert_port(port_list* port)
{
chain_list *not;
char *name;
/*inverted input*/
for ( ; port; port=port->NEXT) {
if (!port->NEGATIV) continue;
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
if (port->DIRECTION!=IN && port->DIRECTION!=INOUT && port->DIRECTION!=TRANSCV)
continue;
port->NEGATIV=0;
#if 1
if (ABL_ATOM(port->ABL)) {
name=getoppositename(ABL_ATOM_VALUE(port->ABL));
if (is_signal(name)) ABL_ATOM_VALUE(port->ABL)=name;
else
{
/*add a not*/
not=createabloper(ABL_NOT);
ABL_ARITY(not)=1;
/*swap pointers references*/
swap_pointers(port->ABL,not);
ABL_CDR(port->ABL)=addchain(NULL,not);
}
}
else
{
switch (ABL_OPER(port->ABL)) {
case ABL_AND: ABL_OPER(port->ABL)=ABL_NAND; break;
case ABL_NAND: ABL_OPER(port->ABL)=ABL_AND; break;
case ABL_OR: ABL_OPER(port->ABL)=ABL_NOR; break;
case ABL_NOR: ABL_OPER(port->ABL)=ABL_OR; break;
case ABL_XOR: ABL_OPER(port->ABL)=ABL_NXOR; break;
case ABL_NXOR: ABL_OPER(port->ABL)=ABL_XOR; break;
case ABL_NOT: /*no need to insert*/
port->ABL=ABL_CADR(port->ABL); continue;
default:
fprintf(stderr,
"invert_port: oper %s forbidden at this level\n",
getabloperuppername(ABL_OPER(port->ABL)));
exit(1);
}
}
/*insert a NOT to match perfectly with cell*/
not=createabloper(ABL_NOT);
ABL_ARITY(not)=1;
/*swap pointers references*/
swap_pointers(port->ABL,not);
ABL_CDR(port->ABL)=addchain(NULL,not);
/* port->ABL = not( not a ) ----> port->ABL = not a */
port->ABL=not;
#else
port->ABL=createablnotexpr(port->ABL);
ABL_ARITY(port->ABL)=1;
#endif
}
}
/******************************************************************************/
/* adapt expr to match cell library */
/* if negativ is non zero opposite value if expr is wanted */
/* evaluate capacitance of leaves */
/******************************************************************************/
static chain_list* loc_adapt_abl(chain_list* expr, float C)
{
cell_list* cell;
port_list* port, *top;
chain_list* abl;
if (!expr) {
fprintf(stderr,"loc_adapt_abl: NULL pointer\n");
exit(1);
}
/*do not need to insert a buffer*/
if (ABL_ATOM(expr)) {
inccapacitance(ABL_ATOM_VALUE(expr),C);
return expr;
}
cell=cell_prepare(expr);
/*arity is too big to be matched*/
if (!cell) {
/*evaluate with the biggest oper*/
int arity=ABL_ARITY(expr); /*memorize arity*/
/*search the biggest arity which matches expr*/
for (ABL_ARITY(expr)=ABL_ARITY(expr)-1 ; ABL_ARITY(expr)>0;
ABL_ARITY(expr)--) {
cell=cell_prepare(expr);
if (cell) break;
}
ABL_ARITY(expr)=arity; /*put back arity*/
if (!cell) {
fprintf(stderr,"Mapping Error: No cell could match '");
display_abl(expr);
if (ABL_ATOM(expr)) fprintf(stderr,"'\n");
else fprintf(stderr,"' (oper arity=%d)\n",ABL_ARITY(expr));
exit(1);
}
/*take the first value*/
for (port=cell->PORT; port; port=port->NEXT) if (port->C!=0) break;
for (abl=ABL_CDR(expr); abl; abl=ABL_CDR(abl)) {
ABL_CAR(abl)=loc_adapt_abl(ABL_CAR(abl),port->C);
}
return expr;
}
top=copyport(cell->PORT); /*because this port can be used later*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
else switch (port->DIRECTION) {
case OUT: case TRISTATE: break;
default:
if (!port->ABL) {
fprintf(stderr,
"loc_adapt_abl: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
port->ABL=loc_adapt_abl(port->ABL,port->C);
}
}
delport(top);
return expr;
}
/******************************************************************************/
/* adapt expr to match cell library */
/* if negativ is non zero opposite value if expr is wanted */
/* evaluate capacitance of leaves */
/******************************************************************************/
extern chain_list* adapt_abl(chain_list* expr)
{
cell_list* cell;
port_list* port, *top;
chain_list* abl;
if (!expr) {
fprintf(stderr,"adapt_abl: NULL pointer\n");
exit(1);
}
cell=cell_prepare(expr);
/*arity is too big to be matched*/
if (!cell) {
int arity;
if (ABL_ATOM(expr)) {
/*no buffer?!!!*/
fprintf(stderr,"Mapping Error: No cell could match '");
display_abl(expr);
fprintf(stderr,"'\n");
exit(1);
}
/*evaluate with the biggest oper*/
arity=ABL_ARITY(expr); /*memorize arity*/
/*search the biggest arity which matches expr*/
for (ABL_ARITY(expr)=ABL_ARITY(expr)-1 ; ABL_ARITY(expr)>0;
ABL_ARITY(expr)--) {
cell=cell_prepare(expr);
if (cell) break;
}
ABL_ARITY(expr)=arity; /*put back arity*/
if (!cell) {
fprintf(stderr,"Mapping Error: No cell could match '");
display_abl(expr);
fprintf(stderr,"' (oper arity=%d)\n",ABL_ARITY(expr));
exit(1);
}
/*take the first value*/
for (port=cell->PORT; port; port=port->NEXT) if (port->C!=0) break;
for (abl=ABL_CDR(expr); abl; abl=ABL_CDR(abl)) {
ABL_CAR(abl)=loc_adapt_abl(ABL_CAR(abl),port->C);
}
return expr;
}
top=copyport(cell->PORT); /*because this port can be used later*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
else switch (port->DIRECTION) {
case OUT: case TRISTATE: break;
default:
if (!port->ABL) {
fprintf(stderr,
"adapt_abl: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
port->ABL=loc_adapt_abl(port->ABL,port->C);
}
}
delport(top);
return expr;
}
/******************************************************************************/
/* adapt biabl to match cell library */
/* evaluate capacitance of leaves */
/******************************************************************************/
extern biabl_list* adapt_bus(biabl_list* biabl)
{
cell_list* cell;
port_list *port, *top;
biabl_list* biabl_aux, *biabl_head;
if (!biabl) {
fprintf(stderr,"adapt_bus: NULL pointer\n");
exit(1);
}
biabl_head=biabl;
/*check if there is a tristate inverter in library*/
/* is-it an advantage to use a tristate inverter here? */
if (is_tristate_inverter_lib() &&
!ABL_ATOM(biabl->VALABL) && ABL_OPER(biabl->VALABL)!=ABL_NOT) {
/*put a NOT in front of expression to be mapped by bus inverter*/
biabl->VALABL=inv_oper(biabl->VALABL,1);
biabl->VALABL=build_negativ(biabl->VALABL);
biabl->VALABL=createablnotexpr(biabl->VALABL);
/* createablnotexpr() can simplify*/
if (!ABL_ATOM(biabl->VALABL)) ABL_ARITY(biabl->VALABL)=1;
}
cell=cell_prepare_bus(biabl);
top=copyport(cell->PORT); /*because this port can be used later*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
else switch (port->DIRECTION) {
case OUT: case TRISTATE: break;
default:
if (!port->ABL) {
fprintf(stderr,
"adapt_bus: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
port->ABL=loc_adapt_abl(port->ABL,port->C);
}
}
delport(top);
/*skip conditions matched by cell*/
for (biabl_aux=cell->BIABL; biabl_aux; biabl_aux=biabl_aux->NEXT)
biabl=biabl->NEXT;
/*look the other blocks*/
if (biabl) {
adapt_bus(biabl);
}
return biabl_head;
}
/******************************************************************************/
/* adapt biabl to match cell library */
/* evaluate capacitance of leaves */
/******************************************************************************/
extern biabl_list* adapt_reg(biabl_list* biabl)
{
cell_list* cell;
port_list *port, *top;
biabl_list* biabl_aux, *biabl_head;
if (!biabl) {
fprintf(stderr,"adapt_reg: NULL pointer\n");
exit(1);
}
biabl_head=biabl;
/*pattern matching*/
cell=cell_prepare_reg(biabl);
top=copyport(cell->PORT); /*because this port can be used later*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
else switch (port->DIRECTION) {
case OUT: case TRISTATE: break;
default:
if (!port->ABL) {
fprintf(stderr,
"adapt_reg: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
port->ABL=loc_adapt_abl(port->ABL,port->C);
}
}
delport(top);
/*skip conditions matched by cell*/
for (biabl_aux=cell->BIABL; biabl_aux; biabl_aux=biabl_aux->NEXT)
biabl=biabl->NEXT;
/*look the other blocks*/
if (biabl) {
adapt_reg(biabl);
}
return biabl_head;
}

View File

@ -0,0 +1,75 @@
/*
* 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 : BooG - evaluate Capacitance
* Date : 2000
* Author : Francois Donnet
*/
#ifndef MAP_ADAPT_H
#define MAP_ADAPT_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/******************************************************************************/
/* swap the contain of 2 abl */
/******************************************************************************/
extern void swap_pointers __P ((chain_list* abl1, chain_list* abl2));
/******************************************************************************/
/* invert abl of port whose NEGATIV flag is set */
/******************************************************************************/
extern void invert_port __P ((port_list* port));
/******************************************************************************/
/* adapt expr to match cell library */
/* if negativ is non zero opposite value if expr is wanted */
/* evaluate capacitance of leaves */
/******************************************************************************/
extern chain_list* adapt_abl __P ((chain_list* expr));
/******************************************************************************/
/* adapt biabl to match cell library */
/* evaluate capacitance of leaves */
/******************************************************************************/
extern biabl_list* adapt_bus __P ((biabl_list* biabl));
/******************************************************************************/
/* adapt biabl to match cell library */
/* evaluate capacitance of leaves */
/******************************************************************************/
extern biabl_list* adapt_reg __P ((biabl_list* biabl));
#endif

View File

@ -0,0 +1,390 @@
/*
* 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 : BooG - mapping standard cells on befig
* Date : 2000
* Author : Francois Donnet
*/
#include <stdlib.h>
#include <stdio.h>
#include <mut.h>
#include <mlo.h>
#include <aut.h>
#include <abl.h>
#include <abe.h>
#include "bog_lib_utils.h"
#include "bog_signal_utils.h"
#include "bog_signal_nameindex.h"
#include "bog_map_pattern.h"
#include "bog_map_abl.h"
#include "bog_map_befig.h"
/*size of memory block*/
#define BLOCK 512
/*table of signal index*/
static authtable* HTABLE=NULL;
/*lofig in creation*/
static lofig_list *lofig;
/*befig in mapping*/
static befig_list* befig;
/*index of losig*/
static long index;
/****************************************************************************/
/*return an unique index for losig in lofig under building */
/****************************************************************************/
extern long getindex()
{
long ret;
ret=index;
index++;
return ret;
}
/****************************************************************************/
/* return the losig named name in lofig under building */
/****************************************************************************/
extern losig_list* seeksignal(char* name)
{
authelem* elem;
elem=searchauthelem(HTABLE,name);
if (!elem) {
fprintf(stderr,"seeksignal: losig '%s' not found\n",name);
exit(1);
}
return (losig_list*) elem->VALUE;
}
/****************************************************************************/
/*return an unique losig named as losig_sce */
/****************************************************************************/
extern losig_list* make_equi(losig_list* losig_sce, losig_list* losig_dest)
{
ptype_list *ptype_dest, *ptype_sce;
chain_list* loconchain;
locon_list* locon;
chain_list* namechain;
char* name;
/*change lofigchain and reference*/
ptype_sce=getptype(losig_sce->USER,LOFIGCHAIN);
ptype_dest=getptype(losig_dest->USER,LOFIGCHAIN);
if (!ptype_sce || !ptype_dest) {
fprintf(stderr,
"make_equi: LOFIGCHAIN is empty for '%s' and/or '%s'\n",
(char*) losig_sce->NAMECHAIN->DATA, (char*) losig_dest->NAMECHAIN->DATA);
exit(1);
}
for (loconchain=(chain_list*) ptype_sce->DATA; loconchain;
loconchain=loconchain->NEXT) {
locon=(locon_list*) loconchain->DATA;
locon->SIG=losig_dest;
ptype_dest->DATA=addchain((chain_list*) ptype_dest->DATA,locon);
}
/*new losig takes all properties*/
for (namechain=losig_dest->NAMECHAIN; namechain; namechain=namechain->NEXT) {
name=(char*) namechain->DATA;
losig_dest->NAMECHAIN=addchain(losig_dest->NAMECHAIN,name);
addauthelem(HTABLE,name,(int)losig_dest);
}
losig_dest->TYPE=losig_sce->TYPE;
/*mask old losig*/
dellosig(lofig,losig_sce->INDEX);
return losig_dest;
}
/****************************************************************************/
/* body of lofig */
/****************************************************************************/
static void add_loins_to_lofig()
{
beaux_list *beaux;
bebux_list *bebux;
beout_list *beout;
bereg_list *bereg;
bebus_list *bebus;
losig_list* output_losig;
/*INTERNAL signals*/
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
/*build loins*/
output_losig=seeksignal(beaux->NAME);
map_abl(lofig,beaux->ABL,output_losig);
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
/*build loins*/
output_losig=seeksignal(bereg->NAME);
map_register(lofig,bereg->BIABL,output_losig);
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
output_losig=seeksignal(bebux->NAME);
/*build loins*/
map_bus(lofig,bebux->BIABL,output_losig);
}
/*EXTERNAL signals*/
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
output_losig=seeksignal(beout->NAME);
/*build loins, put a buffer if needed*/
map_abl(lofig,beout->ABL,output_losig);
}
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
output_losig=seeksignal(bebus->NAME);
/*build loins*/
map_bus(lofig,bebus->BIABL,output_losig);
}
}
/****************************************************************************/
/* build interface, all INTERNAL signals */
/****************************************************************************/
static void add_losig_to_lofig()
{
chain_list *namechain;
beaux_list *beaux;
bebux_list *bebux;
bepor_list *bepor;
bereg_list *bereg;
losig_list *losig;
int index;
/*copy of port signals and create locon for lofig*/
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
namechain=addchain(NULL,bepor->NAME);
index=getindex();
losig=addlosig(lofig,index,namechain,EXTERNAL/*no more capa parameter*/);
addlocon(lofig,bepor->NAME,losig,bepor->DIRECTION);
/*seek fast*/
if (isvss(bepor->NAME)) addauthelem(HTABLE,VSS,(int) losig);
else if (isvdd(bepor->NAME)) addauthelem(HTABLE,VDD,(int) losig);
else addauthelem(HTABLE,bepor->NAME,(int) losig);
}
/*copy of INTERNAL signals*/
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
namechain=addchain(NULL,beaux->NAME);
index=getindex();
losig=addlosig(lofig,index,namechain,INTERNAL/*no more capa parameter*/);
/*seek fast*/
addauthelem(HTABLE,beaux->NAME,(int) losig);
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
namechain=addchain(NULL,bereg->NAME);
index=getindex();
losig=addlosig(lofig,index,namechain,INTERNAL/*no more capa parameter*/);
addauthelem(HTABLE,bereg->NAME,(int) losig);
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
namechain=addchain(NULL,bebux->NAME);
index=getindex();
losig=addlosig(lofig,index,namechain,INTERNAL/*no more capa parameter*/);
addauthelem(HTABLE,bebux->NAME,(int) losig);
}
}
/***************************************************************************/
/* build the one and zero constants */
/***************************************************************************/
static void add_one_zero_losig()
{
chain_list *namechain;
int index;
losig_list* one, *zero;
char * name;
/*add constants signals*/
name=getautoname("one");
/*report same properties*/
putdelay(name,getdelay(getablatomone()));
putcapacitance(name,getdelay(getablatomone()));
namechain=addchain(NULL,name);
index=getindex();
one=addlosig(lofig,index,namechain,INTERNAL/*no more capa parameter*/);
addauthelem(HTABLE,getablatomone(),(int) one);
name=getautoname("zero");
/*report same properties*/
putdelay(name,getdelay(getablatomzero()));
putcapacitance(name,getdelay(getablatomzero()));
namechain=addchain(NULL,name);
index=getindex();
zero=addlosig(lofig,index,namechain,INTERNAL/*no more capa parameter*/);
addauthelem(HTABLE,getablatomzero(),(int) zero);
}
/***************************************************************************/
/* build the one and zero constants if needed in lofig */
/***************************************************************************/
static void add_one_zero_loins()
{
losig_list *losig;
chain_list* abl;
ptype_list* ptype;
/*one*/
losig=seeksignal(getablatomone());
abl=createablatom(getablatomone());
ptype=getptype(losig->USER,LOFIGCHAIN);
/*if not used erase signal*/
if (!ptype || !ptype->DATA) dellosig(lofig,losig->INDEX);
else map_abl(lofig,abl,losig);
freeablexpr(abl);
/*zero*/
losig=seeksignal(getablatomzero());
abl=createablatom(getablatomzero());
ptype=getptype(losig->USER,LOFIGCHAIN);
/*if not used erase signal*/
if (!ptype || !ptype->DATA) dellosig(lofig,losig->INDEX);
else map_abl(lofig,abl,losig);
freeablexpr(abl);
}
/****************************************************************************/
/* build the lofig from befig */
/****************************************************************************/
extern lofig_list* map_befig(befig_list *befig_param, char* lofig_name)
{
if (!befig_param || !lofig_name) {
fprintf(stderr,"map_befig: NULL pointer\n");
exit(1);
}
befig=befig_param;
HTABLE= createauthtable (BLOCK);
index=0;
begin_count_area();
/*header of lofig created*/
lofig=addlofig(lofig_name);
lofig->NAME=lofig_name; /* not to change in lower letters */
/*look inside signals*/
add_losig_to_lofig();
/*to obtain the same order than in befig*/
lofig->LOCON=(locon_list*) reverse((chain_list*) lofig->LOCON);
/*build the constant signal*/
add_one_zero_losig();
/*look inside instances*/
lofigchain(lofig); /*beginning of lofigchain*/
add_loins_to_lofig();
/*add or remove constant instance*/
add_one_zero_loins();
destroyauthtable(HTABLE);
HTABLE=NULL;
index=0;
return lofig;
}
/****************************************************************************/
/* 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=NULL, *pred_low;
loins_list* loins;
if (!lofig) {
fprintf(stderr,"count_instance: NULL pointer\n");
exit(1);
}
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);
}
/*sort*/
while (temp) {
low=temp;
pred_low=NULL;
/*search elem*/
for (ptype=temp; ptype; ptype=ptype->NEXT) {
if (ptype->TYPE<low->TYPE) {
pred_low=pred;
low=ptype;
}
pred=ptype;
}
if (!pred_low) temp=low->NEXT;
else pred_low->NEXT=low->NEXT;
low->NEXT=inst;
inst=low;
}
return inst;
}

View File

@ -0,0 +1,70 @@
/*
* 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 : BooG - mapping standard cells on befig
* Date : 2000
* Author : Francois Donnet
*/
#ifndef MAP_BEFIG_H
#define MAP_BEFIG_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/****************************************************************************/
/*return an unique index for losig in lofig under building */
/****************************************************************************/
extern long getindex __P (());
/****************************************************************************/
/* return the losig named name in lofig under building */
/****************************************************************************/
extern losig_list* seeksignal __P ((char* name));
/****************************************************************************/
/*return an unique losig named as losig_sce */
/****************************************************************************/
extern losig_list* make_equi __P ((losig_list* losig_sce, losig_list* losig_dest));
/****************************************************************************/
/* build the lofig from befig */
/****************************************************************************/
extern lofig_list* map_befig __P ((befig_list *befig, char* lofig_name));
/****************************************************************************/
/* return the number of loins used in lofig */
/****************************************************************************/
extern ptype_list* count_instance __P ((lofig_list* lofig));
#endif

View File

@ -0,0 +1,539 @@
/*
* 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 : BooG - evaluate delay of an abl
* Date : 2000
* Author : Francois Donnet
*/
#include <stdio.h>
#include <mut.h>
#include <abl.h>
#include <abe.h>
#include <aut.h>
#include <mlo.h>
#include "bog_lax_param.h"
#include "bog_lib_utils.h"
#include "bog_signal_utils.h"
#include "bog_signal_nameindex.h"
#include "bog_map_prepare.h"
#include "bog_map_pattern.h"
#include "bog_map_delay.h"
/***************************************************************************/
/*eval delay of a node of an abl */
/* node of an abl (sortance is 1) */
/***************************************************************************/
extern float loc_eval_delay(chain_list *abl, float C)
{
float delay, latest=0;
port_list* port, *top;
cell_list* cell;
int master;
if (!abl) {
fprintf(stderr,"loc_eval_delay: NULL pointer\n");
exit(1);
}
/*constant '1' and '0' are treated as variables*/
if (ABL_ATOM(abl)) return getdelay(ABL_ATOM_VALUE(abl));
/*first recursion?*/
master=first_eval();
/*cell->PORT contains the result of pattern matching*/
cell=cell_pattern(abl);
latest=0;
top=copyport(cell->PORT); /*not to be disturb by recursion*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME)) continue;
if (isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case OUT: case TRISTATE:
/*no delay for output*/
break;
case IN: case INOUT: case TRANSCV:
if (!port->ABL) {
fprintf(stderr,
"loc_eval_delay: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
delay=loc_eval_delay(port->ABL, port->C);
delay+=port->T + port->R*C;
if (latest<delay) latest=delay;
break;
}
}
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
return latest;
}
/***************************************************************************/
/* return the delay of an abl */
/* memorize for this name the delay and the impedance */
/***************************************************************************/
extern float eval_delay(char *name, chain_list *abl)
{
float delay, latest=0;
port_list* port, *top;
cell_list* cell;
int master;
if (!abl) {
fprintf(stderr,"eval_delay: NULL pointer\n");
exit(1);
}
if (!name) {
fprintf(stderr,"eval_delay: signal has no name\n");
exit(1);
}
/*first recursion?*/
master=first_eval();
/*cell->PORT contains the result of pattern matching*/
cell=cell_pattern(abl);
top=copyport(cell->PORT); /*not to be disturb by recursion*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case OUT: case TRISTATE:
/*no delay for output*/
break;
case IN: case INOUT: case TRANSCV:
if (!port->ABL) {
fprintf(stderr,
"eval_delay: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
delay=loc_eval_delay(port->ABL, port->C);
delay+=port->T + port->R * getcapacitance(name);
if (latest<delay) latest=delay;
break;
}
}
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
putdelay(name,latest);
return latest;
}
/******************************************************************************/
/* eval delay of a tristate */
/* memorize for this name the delay and the impedance */
/******************************************************************************/
extern float eval_bus(char* name, biabl_list* biabl)
{
cell_list* cell;
float delay, latest=0;
port_list* port, *top;
int master;
biabl_list* biabl_aux;
if (!name) {
fprintf(stderr,"eval_bus: bus has no name\n");
exit(1);
}
/*first recursion?*/
master=first_eval();
/*cell->PORT contains the result of pattern matching*/
cell=cell_pattern_bus(biabl);
top=copyport(cell->PORT); /*not to be disturb by recursion*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case OUT: case TRISTATE:
/*no delay for output and power supply*/
break;
case IN: case INOUT: case TRANSCV:
if (!port->ABL) {
fprintf(stderr,
"eval_bus: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
delay=loc_eval_delay(port->ABL, port->C);
delay+=port->T + port->R * getcapacitance(name);
if (latest<delay) latest=delay;
break;
}
}
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
/*skip conditions matched by cell*/
for (biabl_aux=cell->BIABL; biabl_aux; biabl_aux=biabl_aux->NEXT)
biabl=biabl->NEXT;
/*look the other blocks*/
if (biabl) {
delay=eval_bus(name,biabl);
if (latest<delay) latest=delay;
}
/*take the latest of tristates on this bus*/
delay=getdelay(name);
if (latest<delay) latest=delay;
putdelay(name,latest);
return latest;
}
/******************************************************************************/
/* eval a register delay */
/* delay evaluated from the setup command */
/* memorize for this name the delay and the impedance */
/******************************************************************************/
extern float eval_reg(char* name, biabl_list* biabl)
{
cell_list* cell;
float delay, latest=0;
port_list* port, *top;
ptype_list* ptype;
int master;
biabl_list* biabl_aux;
if (!biabl) {
fprintf(stderr,"eval_reg: NULL pointer\n");
exit(1);
}
if (!name) {
fprintf(stderr,"eval_reg: reg has no name\n");
exit(1);
}
/*first recursion?*/
master=first_eval();
/*search if flip-flop or latch*/
for (biabl_aux=biabl; biabl_aux; biabl_aux=biabl_aux->NEXT) {
ptype=getptype(biabl_aux->USER,ABL_STABLE);
if (ptype) break;
}
if (ptype) cell=cell_prepare_reg(biabl); /*no time evaluation*/
else cell=cell_pattern_reg(biabl); /*time evaluation*/
/*cell->PORT contains the result of pattern matching*/
top=copyport(cell->PORT); /*not to be disturb by recursion*/
/*delay calculated on ck setup for flip-flop*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME)) continue;
if (isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case OUT: case TRISTATE:
/*no delay for output and power supply*/
break;
case IN: case INOUT: case TRANSCV:
if (port->STABLE) {
if (!port->ABL) {
fprintf(stderr,
"eval_reg: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
delay=loc_eval_delay(port->ABL, port->C);
delay+=port->T + port->R * getcapacitance(name);
if (latest<delay) latest=delay;
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
putdelay(name,latest);
return latest;
}
}
}
/*delay calculate as a tristate for latch */
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME)) continue;
if (isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case OUT: case TRISTATE:
/*no delay for output and power supply*/
break;
case IN: case INOUT: case TRANSCV:
if (!port->ABL) {
fprintf(stderr,
"eval_reg: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
delay=loc_eval_delay(port->ABL, port->C);
delay+=port->T + port->R * getcapacitance(name);
if (latest<delay) latest=delay;
break;
}
}
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
/*skip conditions matched by cell*/
for (biabl_aux=cell->BIABL; biabl_aux; biabl_aux=biabl_aux->NEXT)
biabl=biabl->NEXT;
/*look the other blocks*/
if (biabl) {
delay=eval_reg(name,biabl);
if (latest<delay) latest=delay;
}
putdelay(name,latest);
return latest;
}
/******************************************************************************/
/*eval the delay value of a biabl register */
/******************************************************************************/
extern float eval_value_reg(biabl_list* biabl)
{
cell_list* cell;
float delay, latest=0;
port_list* port, *top;
int master;
biabl_list* biabl_aux;
/*first recursion?*/
master=first_eval();
/*cell->PORT contains the result of pattern matching*/
cell=cell_pattern_reg(biabl);
top=copyport(cell->PORT); /*not to be disturb by recursion*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case OUT: case TRISTATE:
/*no delay for output and power supply*/
break;
case IN: case INOUT: case TRANSCV:
if (!port->STABLE) {
if (!port->ABL) {
fprintf(stderr,
"eval_value_reg: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
delay=loc_eval_delay(port->ABL, port->C);
if (latest<delay) latest=delay;
}
break;
}
}
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
/*skip conditions matched by cell*/
for (biabl_aux=cell->BIABL; biabl_aux; biabl_aux=biabl_aux->NEXT)
biabl=biabl->NEXT;
/*look the other blocks*/
if (biabl) {
delay=eval_value_reg(biabl);
if (latest<delay) latest=delay;
}
return latest;
}
/******************************************************************************/
/* eval clock delay */
/******************************************************************************/
extern float eval_clock_reg(biabl_list* biabl)
{
cell_list* cell;
float delay, latest=0;
port_list* port, *top;
ptype_list* ptype=NULL;
int master;
biabl_list* biabl_aux;
/*first recursion?*/
master=first_eval();
/*search if flip-flop or latch*/
for (biabl_aux=biabl; biabl_aux; biabl_aux=biabl_aux->NEXT) {
ptype=getptype(biabl_aux->USER,ABL_STABLE);
if (ptype) break;
}
if (ptype) cell=cell_prepare_reg(biabl); /*no time evaluation*/
else cell=cell_pattern_reg(biabl); /*time evaluation*/
/*cell->PORT contains the result of pattern matching*/
top=copyport(cell->PORT); /*not to be disturb by recursion*/
/*delay calculated on ck setup for flip-flop*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME)) continue;
if (isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case OUT: case TRISTATE:
/*no delay for output and power supply*/
break;
case IN: case INOUT: case TRANSCV:
if (port->STABLE) {
if (!port->ABL) {
fprintf(stderr,
"eval_clock_reg: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
delay=loc_eval_delay(port->ABL, port->C);
if (latest<delay) latest=delay;
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
return latest;
}
break;
}
}
/*delay calculate as tristate for latch */
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME)) continue;
if (isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case OUT: case TRISTATE:
/*no delay for output and power supply*/
break;
case IN: case INOUT: case TRANSCV:
if (!port->ABL) {
fprintf(stderr,
"eval_clock_reg: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
delay=loc_eval_delay(port->ABL, port->C);
if (latest<delay) latest=delay;
break;
}
}
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
/*skip conditions matched by cell*/
for (biabl_aux=cell->BIABL; biabl_aux; biabl_aux=biabl_aux->NEXT)
biabl=biabl->NEXT;
/*look the other blocks*/
if (biabl) {
delay=eval_clock_reg(biabl);
if (latest<delay) latest=delay;
}
return latest;
}
/******************************************************************************/
/*eval the delay value of a biabl bus */
/******************************************************************************/
extern float loc_eval_bus(biabl_list* biabl, float C)
{
cell_list* cell;
float delay, latest=0;
port_list* port, *top;
int master;
biabl_list* biabl_aux;
/*first recursion?*/
master=first_eval();
/*cell->PORT contains the result of pattern matching*/
cell=cell_pattern_bus(biabl);
top=copyport(cell->PORT); /*not to be disturb by recursion*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case OUT: case TRISTATE:
/*no delay for output and power supply*/
break;
case IN: case INOUT: case TRANSCV:
if (!port->ABL) {
fprintf(stderr,
"eval_value_bus: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
delay=loc_eval_delay(port->ABL, port->C);
delay+=port->T + port->R * C;
if (latest<delay) latest=delay;
break;
}
}
delport(top);
/*free pre-evaluation mecanismus*/
if (master) free_eval();
/*skip conditions matched by cell*/
for (biabl_aux=cell->BIABL; biabl_aux; biabl_aux=biabl_aux->NEXT)
biabl=biabl->NEXT;
/*look the other blocks*/
if (biabl) {
delay=loc_eval_bus(biabl,C);
if (latest<delay) latest=delay;
}
return latest;
}

View File

@ -0,0 +1,87 @@
/*
* 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 : BooG - evaluate delay of an abl
* Date : 2000
* Author : Francois Donnet
*/
#ifndef MAP_DELAY_H
#define MAP_DELAY_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/***************************************************************************/
/*eval delay of a node of an abl */
/* node of an abl (sortance is 1) */
/***************************************************************************/
extern float loc_eval_delay __P ((chain_list *abl, float C));
/***************************************************************************/
/* return the delay of an abl */
/* memorize for this name the delay and the impedance */
/***************************************************************************/
extern float eval_delay __P ((char* name, chain_list *abl));
/******************************************************************************/
/* eval delay of a tristate */
/* memorize for this name the delay and the impedance */
/******************************************************************************/
extern float eval_bus __P ((char* name, biabl_list* biabl));
/******************************************************************************/
/* eval a register delay */
/* delay evaluated from the setup command */
/* memorize for this name the delay and the impedance */
/******************************************************************************/
extern float eval_reg __P ((char* name, biabl_list* biabl));
/******************************************************************************/
/*eval the delay value of a biabl register */
/******************************************************************************/
extern float eval_value_reg __P ((biabl_list* biabl));
/******************************************************************************/
/* eval clock delay */
/******************************************************************************/
extern float eval_clock_reg __P ((biabl_list* biabl));
/******************************************************************************/
/*eval the delay value of a biabl bus */
/******************************************************************************/
extern float loc_eval_bus __P ((biabl_list* biabl, float C));
#endif

View File

@ -0,0 +1,945 @@
/*
* 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 : BooG - pattern matching for shortest delay
* Date : 2000
* Author : Francois Donnet
*/
#ifdef AUTO_HAS_VALUES_H
# include <values.h>
#else
# include <float.h>
# ifndef MAXFLOAT
# define MAXFLOAT FLT_MAX
# endif
#endif
#include <mut.h>
#include <abl.h>
#include <abe.h>
#include <mlo.h>
#include "bog_lax_param.h"
#include "bog_signal_nameindex.h"
#include "bog_lib_utils.h"
#include "bog_lib_cell.h"
#include "bog_normalize_message.h"
#include "bog_normalize_ARITY.h"
#include "bog_map_delay.h"
#include "bog_map_adapt.h"
#include "bog_map_pattern.h"
/*size of memory block*/
#define BLOCK 512
typedef struct delay {
struct delay* NEXT;
float C;
float DELAY;
chain_list* ABL;
} delay_list;
/*heap for delay mecanismus*/
static delay_list* HEAP;
/*list of abl already calculated (not to repeat)*/
static delay_list* ALREADY_EVAL;
/***************************************************************************/
/* take from the heap */
/***************************************************************************/
static delay_list* newdelay()
{
delay_list* new;
int i;
if (!HEAP) {
HEAP=mbkalloc(BLOCK*sizeof(delay_list));
new=HEAP;
for (i = 1; i < BLOCK; i++) {
new->NEXT = new + 1;
new++;
}
new->NEXT = NULL;
}
new=HEAP;
HEAP=HEAP->NEXT;
return new;
}
/******************************************************************************/
/* put back to the heap */
/******************************************************************************/
static void freedelay(delay_list* delay)
{
if (!delay) return;
freedelay(delay->NEXT);
delay->NEXT=HEAP;
HEAP=delay;
}
/******************************************************************************/
/* begin of the abl or not, return 1 if first eval */
/******************************************************************************/
extern int first_eval()
{
if (!ALREADY_EVAL) return 1;
return 0;
}
/******************************************************************************/
/* last recursion on this abl, free all marks */
/******************************************************************************/
extern void free_eval()
{
freedelay(ALREADY_EVAL);
ALREADY_EVAL=NULL;
}
/******************************************************************************/
/* to improve speed do not re-evaluate an abl already done */
/******************************************************************************/
static float find_delay(chain_list* abl, float C)
{
delay_list* delay, *new;
/*search if delay already evaluated*/
for (delay=ALREADY_EVAL; delay; delay=delay->NEXT) {
if (delay->ABL==abl && delay->C==C) break;
}
/*if found*/
if (delay) return delay->DELAY;
new=newdelay();
new->ABL=abl;
new->C=C;
new->DELAY=loc_eval_delay(abl,C);
new->NEXT=ALREADY_EVAL;
ALREADY_EVAL=new;
return new->DELAY;
}
/******************************************************************************/
/* eval opposition of oper1 and oper2 */
/* return 1 if opposite leaves are needed */
/******************************************************************************/
static int sign(int oper1, int oper2)
{
switch (oper1) {
case ABL_AND: case ABL_NAND:
switch (oper2) {
case ABL_AND: case ABL_NAND: return 0;
case ABL_NOR: case ABL_OR: return 1;
default: return 0;
}
case ABL_NOR: case ABL_OR:
switch (oper2) {
case ABL_OR: case ABL_NOR: return 0;
case ABL_NAND: case ABL_AND: return 1;
default: return 0;
}
case ABL_NXOR: case ABL_XOR:
switch (oper2) {
case ABL_XOR: case ABL_NXOR: return 0;
default: return 0;
}
}
return 0;
}
/******************************************************************************/
/* return 0 if not match */
/******************************************************************************/
static int isablcompatible(chain_list* expr, chain_list* pattern, int negativ)
{
char * name;
if (!expr || !pattern) {
fprintf(stderr,"eval_pattern: NULL pointer\n");
exit(1);
}
/*NOT naturally absorbed*/
if (!ABL_ATOM(pattern) && ABL_OPER(pattern)==ABL_NOT) {
return isablcompatible(expr, ABL_CADR(pattern), !negativ);
}
if (!ABL_ATOM(expr) && ABL_OPER(expr)==ABL_NOT) {
return isablcompatible(ABL_CADR(expr), pattern, !negativ);
}
if (ABL_ATOM (pattern) != ABL_ATOM(expr)) return 0;
/*pattern is an atom*/
if (ABL_ATOM(pattern)) {
if (negativ) name=getoppositename(ABL_ATOM_VALUE(expr));
else name=ABL_ATOM_VALUE(expr);
return name==ABL_ATOM_VALUE(pattern);
}
/* not the same arity */
if (ABL_ARITY (expr) != ABL_ARITY (pattern)) return 0;
/*compare operator*/
switch (ABL_OPER(pattern)) {
case ABL_AND: case ABL_NOR:
switch (ABL_OPER(expr)) {
case ABL_AND: case ABL_NOR: if (negativ) return 0; break;
case ABL_NAND: case ABL_OR: if (!negativ) return 0; break;
default: return 0;
}
break;
case ABL_NAND: case ABL_OR:
switch (ABL_OPER(expr)) {
case ABL_AND: case ABL_NOR: if (!negativ) return 0; break;
case ABL_NAND: case ABL_OR: if (negativ) return 0; break;
default: return 0;
}
break;
case ABL_XOR:
switch (ABL_OPER(expr)) {
case ABL_XOR: if (negativ) return 0; break;
case ABL_NXOR: if (!negativ) return 0; break;
default: return 0;
}
break;
case ABL_NXOR:
switch (ABL_OPER(expr)) {
case ABL_XOR: if (!negativ) return 0; break;
case ABL_NXOR: if (negativ) return 0; break;
default: return 0;
}
default: if (ABL_OPER(expr)!=ABL_OPER(pattern)) return 0;
}
negativ=sign(ABL_OPER(expr),ABL_OPER(pattern));
for (pattern = ABL_CDR (pattern); pattern; pattern=ABL_CDR(pattern)) {
expr = ABL_CDR (expr);
if (!isablcompatible (ABL_CAR(expr), ABL_CAR(pattern), negativ)) return 0;
}
return 1;
}
/******************************************************************************/
/*return number of leaves absorbed by a pattern */
/* if there twice the same value in pattern we should have twice a value on */
/* the same place in expr */
/* signal inverted values */
/******************************************************************************/
extern int eval_pattern(chain_list* expr, chain_list* pattern, int negativ)
{
port_list* port;
int ret, sum=0;
char * name;
chain_list* sav_abl;
if (!expr || !pattern) {
fprintf(stderr,"eval_pattern: NULL pointer\n");
exit(1);
}
/*pattern is an atom*/
if (ABL_ATOM (pattern)) {
/*constants MUST match*/
if (ABL_ATOM_VALUE(pattern)==getablatomone()
|| ABL_ATOM_VALUE(pattern)==getablatomzero()) {
/*search constant*/
if (!ABL_ATOM(expr) && ABL_OPER(expr)==ABL_NOT) {
return eval_pattern(ABL_CADR(expr), pattern, !negativ);
}
/*search constant*/
if (!ABL_ATOM(expr)) return 0;
if (negativ) name=getoppositename(ABL_ATOM_VALUE(expr));
else name=ABL_ATOM_VALUE(expr);
return name==ABL_ATOM_VALUE(pattern)?2:0;
}
/*it is a port*/
port=(port_list*) ABL_ATOM_VALUE(pattern);
/*try to absorb the last not*/
if (!ABL_ATOM(expr) && ABL_OPER(expr)==ABL_NOT) {
sav_abl=port->ABL;
ret = eval_pattern(ABL_CADR(expr), pattern, !negativ);
if (ret!=0) return ret;
/*put back last env if failed*/
port->ABL=sav_abl;
}
/*already a leaf on this port*/
if (port->ABL) {
/*one case is possible mux <= x.sel + y.(not sel) */
if (!isablcompatible(expr,port->ABL,negativ!=port->NEGATIV)) return 0;
if (ABL_ATOM(port->ABL) && port->NEGATIV) return 1; /*we need to insert a NOT*/
return 2;
}
port->ABL=expr;
port->NEGATIV=negativ;
if (ABL_ATOM(port->ABL) && port->NEGATIV) return 1; /*we need to insert a NOT*/
return 2;
}
/*if pattern is NOT*/
if (ABL_OPER(pattern)==ABL_NOT) {
return eval_pattern(expr, ABL_CADR(pattern), !negativ);
}
/* pattern isn't an atom and expr is*/
if (ABL_ATOM (expr)) return 0;
/*naturally absorbed*/
if (ABL_OPER(expr)==ABL_NOT) {
return eval_pattern(ABL_CADR(expr), pattern, !negativ);
}
/* not the same arity */
if (ABL_ARITY (expr) != ABL_ARITY (pattern)) return 0;
/*compare operator*/
switch (ABL_OPER(pattern)) {
case ABL_AND: case ABL_NOR:
switch (ABL_OPER(expr)) {
case ABL_AND: case ABL_NOR: if (negativ) return 0; break;
case ABL_NAND: case ABL_OR: if (!negativ) return 0; break;
default: return 0;
}
break;
case ABL_NAND: case ABL_OR:
switch (ABL_OPER(expr)) {
case ABL_AND: case ABL_NOR: if (!negativ) return 0; break;
case ABL_NAND: case ABL_OR: if (negativ) return 0; break;
default: return 0;
}
break;
case ABL_XOR:
switch (ABL_OPER(expr)) {
case ABL_XOR: if (negativ) return 0; break;
case ABL_NXOR: if (!negativ) return 0; break;
default: return 0;
}
break;
case ABL_NXOR:
switch (ABL_OPER(expr)) {
case ABL_XOR: if (!negativ) return 0; break;
case ABL_NXOR: if (negativ) return 0; break;
default: return 0;
}
break;
default: if (ABL_OPER(expr)!=ABL_OPER(pattern)) return 0;
}
negativ=sign(ABL_OPER(expr),ABL_OPER(pattern));
for (pattern = ABL_CDR (pattern); pattern; pattern=ABL_CDR(pattern)) {
expr = ABL_CDR (expr);
ret=eval_pattern (ABL_CAR(expr), ABL_CAR(pattern), negativ);
if (ret==0) return 0;
sum+=ret;
}
return sum;
}
/******************************************************************************/
/* return the cell wich matches expr */
/*fulfill the ORDER field of cell with leaves of pattern matching */
/******************************************************************************/
extern cell_list* cell_pattern(chain_list* expr)
{
cell_list* cell, *best_cell=NULL;
ptype_list* select_cells=NULL, *ptype;
chain_list* save_port=NULL, *chain;
float best_delay=MAXFLOAT;
port_list* port, *best_port = NULL;
int max_integrated=0, integration;
float min_area = MAXFLOAT;
chain_list *not;
if (!expr) {
fprintf(stderr,"cell_pattern: NULL pointer\n");
exit(1);
}
/*create a temporary NOT to match perfectly with cell*/
not=createabloper(ABL_NOT);
ABL_CDR(not)=addchain(NULL,NULL);
ABL_ARITY(not)=1;
/*take those are biggest*/
for (cell=getcell_logic_lib(); cell; cell=cell->NEXT) {
/*improve speed*/
if (ABL_ATOM(cell->ABL)!=ABL_ATOM(expr)) continue;
/*improve speed*/
if (!ABL_ATOM(expr) && ABL_OPER(expr)!=ABL_NOT/*match all*/) {
if (ABL_ARITY(cell->ABL)!=ABL_ARITY(expr)) continue;
switch (ABL_OPER(expr)) {
case ABL_AND: case ABL_NOR:
switch (ABL_OPER(cell->ABL)) {
case ABL_AND: case ABL_NOR: break;
default: continue;
}
break;
case ABL_NAND: case ABL_OR:
switch (ABL_OPER(cell->ABL)) {
case ABL_NAND: case ABL_OR: break;
default: continue;
}
break;
default: if (ABL_OPER(cell->ABL)!=ABL_OPER(expr)) continue;
}
}
/*prepare for use*/
for (port=cell->PORT ; port; port=port->NEXT) port->ABL=NULL;
integration=eval_pattern(expr,cell->ABL, 0);
if (integration==0) continue;
/*take the cell which matches the most of operators*/
if (integration>=max_integrated) {
max_integrated=integration;
select_cells=addptype(select_cells,integration,cell);
}
}
/*optimization in area*/
if (getoptimlax()<=OPTIM_DELAY1) {
min_area=MAXFLOAT;
for (ptype=select_cells; ptype; ptype=ptype->NEXT) {
if (ptype->TYPE<select_cells->TYPE) break;
cell=(cell_list*) ptype->DATA;
if (cell->AREA<min_area) min_area=cell->AREA;
}
}
/*save port from recursive use*/
for (ptype=select_cells; ptype; ptype=ptype->NEXT) {
/*optimization in delay*/
if (ptype->TYPE<select_cells->TYPE) break;
cell=(cell_list*) ptype->DATA;
save_port=addchain(save_port,copyport(cell->PORT));
}
/*put in the same order than select_cells*/
save_port=reverse(save_port);
/*take the fastest*/
chain=save_port;
for (ptype=select_cells; ptype; ptype=ptype->NEXT) {
float delay, max_delay=0;
cell=(cell_list*) ptype->DATA;
if (ptype->TYPE<select_cells->TYPE) break;
/*optimization in area*/
if (getoptimlax()<=OPTIM_DELAY1 && cell->AREA>min_area) {
/*next port list corresponding with next cell*/
chain=chain->NEXT;
continue;
}
/*recursion for delay*/
for (port=(port_list*) chain->DATA; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case IN: case INOUT: case TRANSCV:
if (!port->ABL) {
fprintf(stderr,
"cell_pattern: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
if (port->NEGATIV) {
ABL_CADR(not)=port->ABL;
delay=port->T+find_delay(not, port->C);
}
else delay=port->T+find_delay(port->ABL, port->C);
if (delay>max_delay) max_delay=delay;
break;
}
if (max_delay>best_delay) break;
}
if (max_delay>best_delay) continue;
best_delay=max_delay;
best_port=(port_list*) chain->DATA;
best_cell=cell;
/*next port list corresponding with next cell*/
chain=chain->NEXT;
}
if (!best_cell || (ABL_ATOM(best_cell->ABL) && !ABL_ATOM(expr))
|| (ABL_ATOM(expr) && ABL_ATOM(best_cell->ABL)
&& (ABL_ATOM_VALUE(expr)==getablatomone()
|| ABL_ATOM_VALUE(expr)==getablatomzero())
&& ABL_ATOM_VALUE(expr)!=ABL_ATOM_VALUE(best_cell->ABL)) ) {
fprintf(stderr,"Mapping Error: No cell could match '");
display_abl(expr);
if (ABL_ATOM(expr)) fprintf(stderr,"'\n");
else fprintf(stderr,"' (oper arity=%d)\n",ABL_ARITY(expr));
exit(1);
}
/*put back port values*/
moveport(best_port,best_cell->PORT);
freeptype(select_cells);
for (chain=save_port; chain; chain=chain->NEXT) {
port=(port_list*) chain->DATA;
delport(port);
}
freechain(save_port);
freechain(not);
/*inverted input*/
invert_port(best_cell->PORT); /*invert abl if needed*/
best_cell->DELAY=best_delay;
return best_cell;
}
/******************************************************************************/
/* return the cell tristate wich matches biabl */
/*fulfill the ORDER field of cell with leaves of pattern matching */
/******************************************************************************/
extern cell_list* cell_pattern_bus(biabl_list* biabl)
{
cell_list* cell, *best_cell=NULL;
ptype_list* select_cells=NULL, *ptype;
chain_list* save_port=NULL, *chain;
float best_delay=MAXFLOAT;
port_list *port, *best_port = NULL;
int max_integrated=0, integration;
int test;
float min_area = MAXFLOAT;
biabl_list *biabl_aux, *biabl_cell;
chain_list* not;
/*create a temporary NOT to match perfectly with cell*/
not=createabloper(ABL_NOT);
ABL_CDR(not)=addchain(NULL,NULL);
ABL_ARITY(not)=1;
for (cell=getcell_tristate_lib(); cell; cell=cell->NEXT) {
/*prepare for use*/
for (port=cell->PORT ; port; port=port->NEXT) port->ABL=NULL;
integration=0;
biabl_aux=biabl;
for (biabl_cell=cell->BIABL; biabl_cell; biabl_cell=biabl_cell->NEXT) {
if (!biabl_aux) break;
test=eval_pattern(biabl_aux->CNDABL,biabl_cell->CNDABL,0);
if (test==0) break;
integration+=test;
test=eval_pattern(biabl_aux->VALABL,biabl_cell->VALABL,0);
if (test==0) break;
integration+=test;
biabl_aux=biabl_aux->NEXT;
}
if (biabl_cell) continue;
/*take the cell which matches the most of operators*/
if (integration>=max_integrated) {
max_integrated=integration;
select_cells=addptype(select_cells,integration,cell);
}
}
/*optimization in area*/
if (getoptimlax()<=OPTIM_DELAY1) {
min_area=MAXFLOAT;
for (ptype=select_cells; ptype; ptype=ptype->NEXT) {
if (ptype->TYPE<select_cells->TYPE) break;
cell=(cell_list*) ptype->DATA;
if (cell->AREA<min_area) min_area=cell->AREA;
}
}
/*save port from recursive use*/
for (ptype=select_cells; ptype; ptype=ptype->NEXT) {
/*optimization in delay*/
if (ptype->TYPE<select_cells->TYPE) break;
cell=(cell_list*) ptype->DATA;
save_port=addchain(save_port,copyport(cell->PORT));
}
/*put in the same order than select_cells*/
save_port=reverse(save_port);
/*take the fastest*/
chain=save_port;
for (ptype=select_cells; ptype; ptype=ptype->NEXT) {
float delay, max_delay=0;
cell=(cell_list*) ptype->DATA;
if (ptype->TYPE<select_cells->TYPE) break;
/*optimization in area*/
if (getoptimlax()<=OPTIM_DELAY1 && cell->AREA>min_area) {
/*next port list corresponding with next cell*/
chain=chain->NEXT;
continue;
}
/*recursion for delay*/
for (port=(port_list*) chain->DATA; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case IN: case INOUT: case TRANSCV:
if (!port->ABL) {
fprintf(stderr,
"cell_pattern: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
if (port->NEGATIV) {
ABL_CADR(not)=port->ABL;
delay=port->T+find_delay(not, port->C);
}
else delay=port->T+find_delay(port->ABL, port->C);
if (delay>max_delay) max_delay=delay;
break;
}
if (max_delay>best_delay) break;
}
if (max_delay>best_delay) continue;
best_delay=max_delay;
best_port=(port_list*) chain->DATA;
best_cell=cell;
/*next port list corresponding with next cell*/
chain=chain->NEXT;
}
if (!best_cell) {
fprintf(stderr,"Mapping Error: No cell could match\n");
for ( ; biabl; biabl=biabl->NEXT) {
fprintf(stderr,"BLOCK( ");
display_abl(biabl->CNDABL);
fprintf(stderr," )\n");
fprintf(stderr,"\tbus <= GUARDED ");
display_abl(biabl->VALABL);
fprintf(stderr,";\n");
}
exit(1);
}
/*put back port values*/
moveport(best_port,best_cell->PORT);
freeptype(select_cells);
for (chain=save_port; chain; chain=chain->NEXT) {
port=(port_list*) chain->DATA;
delport(port);
}
freechain(save_port);
freechain(not);
/*inverted input*/
invert_port(best_cell->PORT); /*invert abl if needed*/
best_cell->DELAY=best_delay;
return best_cell;
}
/******************************************************************************/
/* return the cell register which matches biabl */
/*fulfill the ORDER field of cell with leaves of pattern matching */
/******************************************************************************/
extern cell_list* cell_pattern_reg(biabl_list* biabl)
{
cell_list* cell, *best_cell=NULL;
port_list *port, *best_port = NULL;
ptype_list* select_cells=NULL, *ptype;
chain_list* save_port=NULL, *chain;
float best_delay=MAXFLOAT;
int max_integrated=0, integration;
int test;
float min_area = MAXFLOAT;
biabl_list *biabl_aux, *biabl_cell;
chain_list *not;
/*create a temporary NOT to match perfectly with cell*/
not=createabloper(ABL_NOT);
ABL_CDR(not)=addchain(NULL,NULL);
ABL_ARITY(not)=1;
cell=getcell_register_lib();
for ( ; cell; cell=cell->NEXT) {
/*prepare cell*/
for (port=cell->PORT ; port; port=port->NEXT) port->ABL=NULL;
integration=0;
biabl_aux=biabl;
for (biabl_cell=cell->BIABL; biabl_cell; biabl_cell=biabl_cell->NEXT) {
if (!biabl_aux) break;
test=eval_pattern(biabl_aux->CNDABL,biabl_cell->CNDABL,0);
if (test==0) break;
integration+=test;
test=eval_pattern(biabl_aux->VALABL,biabl_cell->VALABL,0);
if (test==0) break;
integration+=test;
biabl_aux=biabl_aux->NEXT;
}
if (biabl_cell) continue;
/*take the cell which matches the most of operators*/
if (integration>=max_integrated) {
max_integrated=integration;
select_cells=addptype(select_cells,integration,cell);
}
}
/*optimization in area*/
if (getoptimlax()<=OPTIM_DELAY1) {
min_area=MAXFLOAT;
for (ptype=select_cells; ptype; ptype=ptype->NEXT) {
if (ptype->TYPE<select_cells->TYPE) break;
cell=(cell_list*) ptype->DATA;
if (cell->AREA<min_area) min_area=cell->AREA;
}
}
/*save port from recursive use*/
for (ptype=select_cells; ptype; ptype=ptype->NEXT) {
/*optimization in delay*/
if (ptype->TYPE<select_cells->TYPE) break;
cell=(cell_list*) ptype->DATA;
save_port=addchain(save_port,copyport(cell->PORT));
}
/*put in the same order than select_cells*/
save_port=reverse(save_port);
/*take the fastest*/
chain=save_port;
for (ptype=select_cells; ptype; ptype=ptype->NEXT) {
float delay, max_delay=0;
cell=(cell_list*) ptype->DATA;
if (ptype->TYPE<select_cells->TYPE) break;
/*optimization in area*/
if (getoptimlax()<=OPTIM_DELAY1 && cell->AREA>min_area) {
/*next port list corresponding with next cell*/
chain=chain->NEXT;
continue;
}
/*recursion for delay*/
for (port=(port_list*) chain->DATA; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
switch (port->DIRECTION) {
case IN: case INOUT: case TRANSCV:
if (!port->ABL) {
fprintf(stderr,
"cell_pattern: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
if (port->NEGATIV) {
ABL_CADR(not)=port->ABL;
delay=port->T+find_delay(not, port->C);
}
else delay=port->T+find_delay(port->ABL, port->C);
if (delay>max_delay) max_delay=delay;
break;
}
if (max_delay>best_delay) break;
}
if (max_delay>best_delay) continue;
best_delay=max_delay;
best_port=(port_list*) chain->DATA;
best_cell=cell;
/*next port list corresponding with next cell*/
chain=chain->NEXT;
}
if (!best_cell) {
fprintf(stderr,"Mapping Error: No cell could match\n");
for ( ; biabl; biabl=biabl->NEXT) {
fprintf(stderr,"BLOCK( ");
display_abl(biabl->CNDABL);
fprintf(stderr," )\n");
fprintf(stderr,"\treg <= GUARDED ");
display_abl(biabl->VALABL);
fprintf(stderr,";\n");
}
exit(1);
}
/*put back port values*/
moveport(best_port,best_cell->PORT);
freeptype(select_cells);
for (chain=save_port; chain; chain=chain->NEXT) {
port=(port_list*) chain->DATA;
delport(port);
}
freechain(save_port);
freechain(not);
/*inverted input*/
invert_port(best_cell->PORT); /*invert abl if needed*/
best_cell->DELAY=best_delay;
return best_cell;
}
/************************************************************************/
/* to locate easier the port of bepor in the abl for later use */
/* do pointing the leaf of abl on the elements of port and sorted */
/* like bepor */
/* returning an abl with each leaf pointing on one port element */
/************************************************************************/
extern chain_list* build_reference(befig_list* befig, port_list* port, port_list* internal_port, chain_list* abl)
{
chain_list* chain;
bepor_list* bepor;
port_list* port_aux;
if (ABL_ATOM(abl)) {
/*constante not touched*/
if (ABL_ATOM_VALUE(abl)==getablatomone()
|| ABL_ATOM_VALUE(abl)==getablatomzero()
|| ABL_ATOM_VALUE(abl)==getablatomtristate()
|| ABL_ATOM_VALUE(abl)==getablatomdc()) return abl;
/*internal reference already created*/
for (port_aux=internal_port; port_aux; port_aux=port_aux->NEXT) {
if (port_aux==(port_list*)ABL_ATOM_VALUE(abl)) return abl;
}
/*create reference for port*/
for (bepor=befig->BEPOR; bepor && port; bepor=bepor->NEXT) {
if (bepor->NAME==ABL_ATOM_VALUE(abl)) break;
port=port->NEXT;
}
if (!bepor || !port) {
fprintf(stderr,"build_reference: '%s' not found in port in cell '%s'\n",
ABL_ATOM_VALUE(abl),befig->NAME);
exit(1);
}
/*refer to new port*/
ABL_ATOM_VALUE(abl)=(chain_list*)port;
return abl; /*head unchanged*/
}
for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
ABL_CAR(chain)=build_reference(befig,port,internal_port,ABL_CAR(chain));
}
/*mark if STABLE*/
if (ABL_OPER(abl)==ABL_STABLE) {
port= (port_list*) ABL_ATOM_VALUE(ABL_CADR(abl));
port->STABLE=1;
}
return abl; /*head unchanged*/
}
/************************************************************************/
/* create a pseudo port, if an internal register is used in abl */
/* return the list of pseudo port */
/************************************************************************/
extern port_list* internal_reference(befig_list* befig, port_list* port, chain_list* abl)
{
chain_list* chain;
bereg_list* bereg;
port_list* port_aux;
if (ABL_ATOM(abl)) {
/*constante not touched*/
if (ABL_ATOM_VALUE(abl)==getablatomone()
|| ABL_ATOM_VALUE(abl)==getablatomzero()
|| ABL_ATOM_VALUE(abl)==getablatomtristate()
|| ABL_ATOM_VALUE(abl)==getablatomdc()) return port;
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
if (bereg->NAME==ABL_ATOM_VALUE(abl)) break;
}
if (!bereg) return port;
/*check if internal reference already exists*/
for (port_aux=port; port_aux; port_aux=port_aux->NEXT) {
if (port_aux->NAME==bereg->NAME) return port;
}
/*create a new internal port*/
port_aux=newport();
port_aux->NEXT=port;
port_aux->NAME=bereg->NAME;
port_aux->DIRECTION=INOUT;
/*refer to new port*/
ABL_ATOM_VALUE(abl)=(chain_list*)port_aux;
return port_aux;
}
for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
port=internal_reference(befig,port,ABL_CAR(chain));
}
return port;
}

View File

@ -0,0 +1,96 @@
/*
* 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 : BooG - pattern matching for shortest delay
* Date : 2000
* Author : Francois Donnet
*/
#ifndef MAP_PATTERN_H
#define MAP_PATTERN_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/******************************************************************************/
/*return number of leaves absorbed by a pattern */
/* if there twice the same value in pattern we should have twice a value on */
/* the same place in expr */
/* signal inverted values */
/******************************************************************************/
extern int eval_pattern __P ((chain_list* expr, chain_list* pattern, int negativ));
/******************************************************************************/
/* return the cell wich matches expr */
/*fulfill the ORDER field of cell with leaves of pattern matching */
/******************************************************************************/
extern cell_list* cell_pattern __P ((chain_list* expr));
/******************************************************************************/
/* return the cell tristate wich matches biabl */
/*fulfill the ORDER field of cell with leaves of pattern matching */
/******************************************************************************/
extern cell_list* cell_pattern_bus __P ((biabl_list* biabl));
/******************************************************************************/
/* return the cell register wich matches biabl */
/*fulfill the ORDER field of cell with leaves of pattern matching */
/******************************************************************************/
extern cell_list* cell_pattern_reg __P ((biabl_list* biabl));
/************************************************************************/
/* to locate easier the port of bepor in the abl for later use */
/* do pointing the leaf of abl on the elements of port and sorted */
/* like bepor */
/* returning an abl with each leaf pointing on one port element */
/************************************************************************/
extern chain_list* build_reference __P ((befig_list* befig, port_list* port, port_list* internal_port, chain_list* abl));
/************************************************************************/
/* create a pseudo port, if an internal register is used in abl */
/* return the list of pseudo port */
/************************************************************************/
extern port_list* internal_reference __P ((befig_list* befig, port_list* port, chain_list* abl));
/******************************************************************************/
/* begin of the abl or not, return 1 if first eval */
/******************************************************************************/
extern int first_eval __P (());
/******************************************************************************/
/* last recursion on this abl, free all marks */
/******************************************************************************/
extern void free_eval __P (());
#endif

View File

@ -0,0 +1,251 @@
/*
* 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 : BooG - pattern matching for biggest cells
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <mlo.h>
#include <abl.h>
#include <abe.h>
#include "bog_lax_param.h"
#include "bog_lib_utils.h"
#include "bog_lib_cell.h"
#include "bog_signal_nameindex.h"
#include "bog_normalize_message.h"
#include "bog_normalize_ARITY.h"
#include "bog_map_pattern.h"
#include "bog_map_adapt.h"
#include "bog_map_prepare.h"
/******************************************************************************/
/* return the cell which matches expr, if return NULL expr arity is too big */
/* (maybe few inversions should be done) */
/******************************************************************************/
extern cell_list* cell_prepare(chain_list* expr)
{
cell_list* cell, *best_cell=NULL;
port_list* port;
int max_integrated=0, integration;
if (!expr) {
fprintf(stderr,"cell_prepare: NULL pointer\n");
exit(1);
}
for (cell=getcell_logic_lib(); cell; cell=cell->NEXT) {
/*improve speed*/
if (ABL_ATOM(cell->ABL)!=ABL_ATOM(expr)) continue;
/*improve speed*/
if (!ABL_ATOM(expr) && ABL_OPER(expr)!=ABL_NOT/*match all*/) {
if (ABL_ARITY(cell->ABL)!=ABL_ARITY(expr)) continue;
switch (ABL_OPER(expr)) {
case ABL_AND: case ABL_NOR:
switch (ABL_OPER(cell->ABL)) {
case ABL_AND: case ABL_NOR: break;
default: continue;
}
break;
case ABL_NAND: case ABL_OR:
switch (ABL_OPER(cell->ABL)) {
case ABL_NAND: case ABL_OR: break;
default: continue;
}
break;
default: if (ABL_OPER(cell->ABL)!=ABL_OPER(expr)) continue;
}
}
for (port=cell->PORT ; port; port=port->NEXT) port->ABL=NULL;
integration=eval_pattern(expr,cell->ABL, 0);
if (integration==0) continue;
/*take the cell which matches the most of operators*/
if (integration>max_integrated) {
max_integrated=integration;
best_cell=cell;
}
else if (integration==max_integrated) {
/*take the litlest*/
if (cell->AREA<best_cell->AREA) {
best_cell=cell;
}
}
}/*end of loop on cell*/
/*if arity is too high then operator matched by buffer*/
if (!best_cell || (ABL_ATOM(best_cell->ABL) && !ABL_ATOM(expr))) return NULL;
else {
invert_port(best_cell->PORT); /*invert abl if needed*/
return best_cell;
}
}
/******************************************************************************/
/*return the bus which matches (maybe few inversions should be done) */
/******************************************************************************/
extern cell_list* cell_prepare_bus(biabl_list* biabl)
{
cell_list* cell, *best_cell=NULL;
port_list *port;
int max_integrated=0, integration;
int test;
biabl_list *biabl_cell, *biabl_aux;
if (!biabl) {
fprintf(stderr,"cell_prepare_bus: NULL pointer\n");
exit(1);
}
for (cell=getcell_tristate_lib(); cell; cell=cell->NEXT) {
/*prepare cell*/
for (port=cell->PORT ; port; port=port->NEXT) port->ABL=NULL;
integration=0;
biabl_aux=biabl;
for (biabl_cell=cell->BIABL; biabl_cell; biabl_cell=biabl_cell->NEXT) {
if (!biabl_aux) break;
test=eval_pattern(biabl_aux->CNDABL,biabl_cell->CNDABL,0);
if (test==0) break;
integration+=test;
test=eval_pattern(biabl_aux->VALABL,biabl_cell->VALABL,0);
if (test==0) break;
integration+=test;
biabl_aux=biabl_aux->NEXT;
}
if (biabl_cell) continue;
/*take the cell which matches the most of operators*/
if (integration>max_integrated) {
max_integrated=integration;
best_cell=cell;
}
else if (integration==max_integrated) {
/*take the litlest*/
if (cell->AREA<best_cell->AREA) {
best_cell=cell;
}
}
}
if (best_cell) {
invert_port(best_cell->PORT); /*invert abl if needed*/
return best_cell;
}
fprintf(stderr,"Mapping Error: No cell could match\n");
for ( ; biabl; biabl=biabl->NEXT) {
fprintf(stderr,"BLOCK( ");
display_abl(biabl->CNDABL);
fprintf(stderr," )\n");
fprintf(stderr,"\tbus <= GUARDED ");
display_abl(biabl->VALABL);
fprintf(stderr,";\n");
}
exit(1);
}
/******************************************************************************/
/*return the reg which matches (maybe few inversions should be done) */
/******************************************************************************/
extern cell_list* cell_prepare_reg(biabl_list* biabl)
{
cell_list* cell, *best_cell=NULL;
port_list *port;
int max_integrated=0, integration;
int test;
biabl_list *biabl_cell, *biabl_aux;
if (!biabl) {
fprintf(stderr,"cell_prepare_reg: NULL pointer\n");
exit(1);
}
cell=getcell_register_lib();
for ( ; cell; cell=cell->NEXT) {
/*prepare cell*/
for (port=cell->PORT; port; port=port->NEXT) port->ABL=NULL;
integration=0;
biabl_aux=biabl;
for (biabl_cell=cell->BIABL; biabl_cell; biabl_cell=biabl_cell->NEXT) {
if (!biabl_aux) break;
test=eval_pattern(biabl_aux->CNDABL,biabl_cell->CNDABL,0);
if (test==0) break;
integration+=test;
test=eval_pattern(biabl_aux->VALABL,biabl_cell->VALABL,0);
if (test==0) break;
integration+=test;
biabl_aux=biabl_aux->NEXT;
}
if (biabl_cell) continue;
/*take the cell which matches the most of operators*/
if (integration>max_integrated) {
max_integrated=integration;
best_cell=cell;
}
else if (integration==max_integrated) {
/*take the litlest*/
if (cell->AREA<best_cell->AREA) {
best_cell=cell;
}
}
}
if (best_cell) {
invert_port(best_cell->PORT); /*invert abl if needed*/
return best_cell;
}
fprintf(stderr,"Mapping Error: No cell could match\n");
for ( ; biabl; biabl=biabl->NEXT) {
fprintf(stderr,"BLOCK( ");
display_abl(biabl->CNDABL);
fprintf(stderr," )\n");
fprintf(stderr,"\treg <= GUARDED ");
display_abl(biabl->VALABL);
fprintf(stderr,";\n");
}
exit(1);
}

View File

@ -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 : BooG - pattern matching for biggest cells
* Date : 2000
* Author : Francois Donnet
*/
#ifndef MAP_PREPARE_H
#define MAP_PREPARE_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/******************************************************************************/
/* return the cell which matches expr, if return NULL expr arity is too big */
/* (maybe few inversions should be done) */
/******************************************************************************/
extern cell_list* cell_prepare __P ((chain_list* expr));
/******************************************************************************/
/*return the bus which matches (maybe few inversions should be done) */
/******************************************************************************/
extern cell_list* cell_prepare_bus __P ((biabl_list* biabl));
/******************************************************************************/
/*return the reg which matches (maybe few inversions should be done) */
/******************************************************************************/
extern cell_list* cell_prepare_reg __P ((biabl_list* biabl));
#endif

View File

@ -0,0 +1,104 @@
/*
* 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 : BooG - put arity notion in abl
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <abl.h>
#include <abe.h>
#include "bog_signal_utils.h"
#include "bog_normalize_ARITY.h"
/***************************************************************************/
/* put arity operator in abl->DATA->NEXT field */
/* Warning: simpablexpr() do not work anymore after pulling arity */
/***************************************************************************/
extern void put_arity_abl (chain_list* abl)
{
chain_list* pattern;
int arity;
/*pattern is an atom*/
if (ABL_ATOM (abl)) return;
arity=0;
for (pattern = ABL_CDR (abl); pattern; pattern=ABL_CDR(pattern)) {
arity++;
put_arity_abl((chain_list*)ABL_CAR(pattern));
}
ABL_ARITY(abl)=arity;
return ;
}
/***************************************************************************/
/* count the arity of each operator */
/***************************************************************************/
extern void put_arity(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) {
put_arity_abl(beout->ABL);
}
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
put_arity_abl(beaux->ABL);
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
put_arity_abl(biabl->CNDABL);
put_arity_abl(biabl->VALABL);
}
}
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) {
put_arity_abl(biabl->CNDABL);
put_arity_abl(biabl->VALABL);
}
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) {
put_arity_abl(biabl->CNDABL);
put_arity_abl(biabl->VALABL);
}
}
}

View File

@ -0,0 +1,60 @@
/*
* 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 : BooG - put arity notion in abl
* Date : 2000
* Author : Francois Donnet
*/
#ifndef NORMALIZE_ARITY_H
#define NORMALIZE_ARITY_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/*head operator arity*/
/* Warning: simpablexpr() do not work anymore after pulling arity */
#define ABL_ARITY(abl) ((int)ABL_CDR((chain_list*)ABL_CAR(abl)))
/***************************************************************************/
/* put arity operator in abl->DATA->NEXT field */
/* Warning: simpablexpr() do not work anymore after pulling arity */
/***************************************************************************/
extern void put_arity_abl __P ((chain_list* abl));
/***************************************************************************/
/* arity is put on abl->DATA->NEXT field for each operator */
/***************************************************************************/
extern void put_arity __P ((befig_list* befig));
#endif

View File

@ -0,0 +1,601 @@
/*
* 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 : BooG - 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 "bog_lax_param.h"
#include "bog_signal_utils.h"
#include "bog_normalize_message.h"
#include "bog_normalize_ARITY.h"
#include "bog_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);
/*put an arity if there was already an arity*/
if (ABL_ARITY(equi->ABL)!=0) put_arity_abl(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);
/*put an arity if there was already an arity*/
if (ABL_ARITY(equi->ABL)!=0) put_arity_abl(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() */
delsignal(bebux->NAME);
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() */
delsignal(bereg->NAME);
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() */
delsignal(beaux->NAME);
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;
}

View File

@ -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 : BooG - 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

View File

@ -0,0 +1,123 @@
/*
* 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 : BooG - quick simplify Don't Care
* Date : 2000
* Author : Francois Donnet
*/
#include <stdlib.h>
#include <stdio.h>
#include <mut.h>
#include <abl.h>
#include <abe.h>
#include "bog_normalize_DC.h"
/***************************************************************************/
/* choose '1' or '0' to simplify the expression as well as we can */
/***************************************************************************/
static void find_d_z_abl(chain_list* abl, int value)
{
if (ABL_ATOM(abl)) {
if (ABL_ATOM_VALUE(abl)==getablatomdc()/* = namealloc("'d'")*/) {
/*non standard IEEE VHDL*/ /*it means "don't care"*/
/* we can put zero either one, only to simplify*/
ABL_ATOM_VALUE(abl)=value?getablatomone():getablatomzero();
}
else if (ABL_ATOM_VALUE(abl)==getablatomtristate()/* =namealloc("'z'")*/){
/*no drive on signal*/
/* a pull-up is done for better conductance*/
ABL_ATOM_VALUE(abl)=getablatomone()/* = namealloc("'1'")*/;
}
}
/*the first operator influences the most*/
switch (ABL_OPER(abl)) {
case ABL_OR: case ABL_NOR: value=1;
case ABL_AND: case ABL_NAND: value=0;
}
/*for each operator*/
for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) {
find_d_z_abl(ABL_CAR(abl),value);
}
}
/****************************************************************************/
/* change 'z' and 'd' occurence in '0' or '1' in all expressions of befig */
/****************************************************************************/
extern void remove_DC(befig_list* befig)
{
beaux_list *beaux;
bebux_list *bebux;
bebus_list *bebus;
beout_list *beout;
bereg_list *bereg;
biabl_list *biabl;
if (!befig) {
fprintf(stderr,"remove_Z_D: NULL pointer\n");
exit(1);
}
/*INTERNAL signals*/
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
find_d_z_abl(beaux->ABL,1);
}
/*INTERNAL bus*/
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) {
find_d_z_abl(biabl->CNDABL,1);
find_d_z_abl(biabl->VALABL,1);
}
}
/*register and latch*/
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
find_d_z_abl(biabl->CNDABL,1);
find_d_z_abl(biabl->VALABL,1);
}
}
/*EXTERNAL signals*/
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
find_d_z_abl(beout->ABL,1);
}
/* bussed output */
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) {
find_d_z_abl(biabl->CNDABL,1);
find_d_z_abl(biabl->VALABL,1);
}
}
}

View File

@ -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 : BooG - quick simplify Don't Care
* Date : 2000
* Author : Francois Donnet
*/
#ifndef NORMALIZE_DC_H
#define NORMALIZE_DC_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/****************************************************************************/
/* change 'z' and 'd' occurence in '0' or '1' in all expressions of befig */
/****************************************************************************/
extern void remove_DC __P ((befig_list* befig));
#endif

View File

@ -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 : BooG - display message
* Date : 2000
* Author : Francois Donnet
*/
#include <stdlib.h>
#include <stdio.h>
#include <mut.h>
#include <abl.h>
#include "bog_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");
}

View File

@ -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 : BooG - 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

View File

@ -0,0 +1,403 @@
/*
* 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 : BooG - change name signals
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <abl.h>
#include <aut.h>
#include <abe.h>
#include "bog_signal_nameindex.h"
#include "bog_normalize_nameindex.h"
/*size of memory block*/
#define BLOCK 256
static authtable* HTABLE;
static ptype_list *VECTOR;
/***************************************************************************/
/* change name of vector */
/***************************************************************************/
static void changename(chain_list* abl)
{
authelem *elem;
if (ABL_ATOM(abl)) {
elem=searchauthelem(HTABLE,ABL_ATOM_VALUE(abl));
if (!elem) return;
ABL_ATOM_VALUE(abl)=(char*) elem->VALUE;
return;
}
for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) {
changename(ABL_CAR(abl));
}
}
/***************************************************************************/
/* return 1 if there some vector index to change */
/***************************************************************************/
static int control_vector()
{
ptype_list* ptype;
char *radical=NULL, *name;
int index=0;
char memo;
int ret=0;
memo=SEPAR; /*separator for nameindex()*/
for (ptype=VECTOR; ptype; ptype=ptype->NEXT) {
if (radical==(char*) ptype->DATA) {
index++;
if (index!=ptype->TYPE) {
ret=1;
SEPAR=' ';
name=nameindex((char*) ptype->DATA,ptype->TYPE);
SEPAR='_';
/*build a bit from a vector*/
addauthelem(HTABLE,name,(int)nameindex(ptype->DATA,ptype->TYPE));
}
}
else {
radical=(char*) ptype->DATA;
index=ptype->TYPE;
}
}
SEPAR=memo;
return ret;
}
/***************************************************************************/
/*insert in a sort list a vector */
/***************************************************************************/
static void addvector(char *name)
{
char *radical;
int index;
ptype_list *pred=NULL, *ptype;
radical=vectorradical(name);
index=vectorindex(name);
for (ptype=VECTOR; ptype; ptype=ptype->NEXT) {
if ((char*)ptype->DATA==radical) {
for ( ; ptype; ptype=ptype->NEXT) {
if ((char*)ptype->DATA!=radical || ptype->TYPE>index) break;
pred=ptype;
}
break;
}
pred=ptype;
}
ptype=addptype(ptype,index,radical);
if (pred) pred->NEXT=ptype;
else VECTOR=ptype;
}
/***************************************************************************/
/*if a vector has some space left between 2 bits, change vector in one to */
/*one bit no to corrupt befig */
/***************************************************************************/
extern void normalize_nameindex(befig_list* befig)
{
bebus_list* bebus;
beaux_list* beaux;
beout_list* beout;
bereg_list* bereg;
bebux_list* bebux;
biabl_list* biabl;
authelem *elem;
HTABLE=createauthtable (BLOCK);
VECTOR=NULL;
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
if (vectorindex(beaux->NAME)==-1) continue;
addvector(beaux->NAME);
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
if (vectorindex(bereg->NAME)==-1) continue;
addvector(bereg->NAME);
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
if (vectorindex(bebux->NAME)==-1) continue;
addvector(bebux->NAME);
}
/*is there any space in vectors?*/
if (!control_vector()) {
/*free table*/
destroyauthtable(HTABLE);
HTABLE=NULL;
if (VECTOR) freeptype(VECTOR);
VECTOR=NULL;
return;
}
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
elem=searchauthelem(HTABLE,beaux->NAME);
if (elem) beaux->NAME=(char*) elem->VALUE;
changename(beaux->ABL);
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
elem=searchauthelem(HTABLE,bereg->NAME);
if (elem) bereg->NAME=(char*) elem->VALUE;
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
changename(biabl->CNDABL);
changename(biabl->VALABL);
}
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
elem=searchauthelem(HTABLE,bebux->NAME);
if (elem) bebux->NAME=(char*) elem->VALUE;
for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) {
changename(biabl->CNDABL);
changename(biabl->VALABL);
}
}
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
/*bepor vector do not need to be controled*/
changename(beout->ABL);
}
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
/*bepor vector do not need to be controled*/
for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) {
changename(biabl->CNDABL);
changename(biabl->VALABL);
}
}
/*free table*/
destroyauthtable(HTABLE);
HTABLE=NULL;
freeptype(VECTOR);
VECTOR=NULL;
}
/***************************************************************************/
/* sort vector in order */
/***************************************************************************/
static beaux_list* sortgeneric(beaux_list* top, beaux_list* generic)
{
char *radical=NULL;
beaux_list* pred=NULL, *beaux;
int index;
radical=vectorradical(generic->NAME);
index=vectorindex(generic->NAME);
/*search the good place*/
for (beaux=top; beaux; beaux=beaux->NEXT) {
if (radical==vectorradical(beaux->NAME)) {
for ( ; beaux; beaux=beaux->NEXT) {
if (radical!=vectorradical(beaux->NAME)
|| index<vectorindex(beaux->NAME)) break;
pred=beaux;
}
break;
}
pred=beaux;
}
generic->NEXT=beaux;
if (!pred) return generic;
pred->NEXT=generic;
return top;
}
/***************************************************************************/
/* sort vectors to be recognized by parser/driver */
/***************************************************************************/
extern void sort_vector(befig_list* befig)
{
beaux_list* beaux, *new_beaux=NULL, *pred_beaux=NULL, *beaux_next;
bereg_list* bereg, *new_bereg=NULL, *pred_bereg=NULL, *bereg_next;
bebux_list* bebux, *new_bebux=NULL, *pred_bebux=NULL, *bebux_next;
for (beaux=befig->BEAUX; beaux; ) {
if (vectorindex(beaux->NAME)!=-1) {
if (pred_beaux) pred_beaux->NEXT=beaux->NEXT;
else befig->BEAUX=beaux->NEXT;
beaux_next=beaux->NEXT;
new_beaux=sortgeneric(new_beaux,beaux);
beaux=beaux_next;
}
else {
pred_beaux=beaux;
beaux=beaux->NEXT;
}
}
/*add sort list*/
if (new_beaux) {
/*reach last*/
for (beaux=new_beaux; beaux->NEXT; beaux=beaux->NEXT) ;
beaux->NEXT=befig->BEAUX;
befig->BEAUX=new_beaux;
}
for (bebux=befig->BEBUX; bebux; ) {
if (vectorindex(bebux->NAME)!=-1) {
if (pred_bebux) pred_bebux->NEXT=bebux->NEXT;
else befig->BEBUX=bebux->NEXT;
bebux_next=bebux->NEXT;
new_bebux=(bebux_list*)
sortgeneric((beaux_list*) new_bebux,(beaux_list*) bebux);
bebux=bebux_next;
}
else {
pred_bebux=bebux;
bebux=bebux->NEXT;
}
}
/*add sort list*/
if (new_bebux) {
/*reach last*/
for (bebux=new_bebux; bebux->NEXT; bebux=bebux->NEXT) ;
/*connect*/
bebux->NEXT=befig->BEBUX;
befig->BEBUX=new_bebux;
}
for (bereg=befig->BEREG; bereg; ) {
if (vectorindex(bereg->NAME)!=-1) {
if (pred_bereg) pred_bereg->NEXT=bereg->NEXT;
else befig->BEREG=bereg->NEXT;
bereg_next=bereg->NEXT;
new_bereg=(bereg_list*)
sortgeneric((beaux_list*) new_bereg,(beaux_list*) bereg);
bereg=bereg_next;
}
else {
pred_bereg=bereg;
bereg=bereg->NEXT;
}
}
/*add sort list*/
if (new_bereg) {
for (bereg=new_bereg; bereg->NEXT; bereg=bereg->NEXT) ;
/*reach last*/
bereg->NEXT=befig->BEREG;
befig->BEREG=new_bereg;
}
}
/***************************************************************************/
/* some radical name can generate conflict with automatic indexation */
/*change name not to disturb algorithm */
/***************************************************************************/
extern void change_radical(befig_list* befig)
{
bebus_list* bebus;
beaux_list* beaux;
beout_list* beout;
bereg_list* bereg;
bebux_list* bebux;
biabl_list* biabl;
char* name;
HTABLE=createauthtable (BLOCK);
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
if (!forbid_radical(beaux->NAME)) continue;
name=beaux->NAME; /*name begins by MBK_NOT_..... */
beaux->NAME=getautoname(beaux->NAME);
addauthelem(HTABLE,name,(int)beaux->NAME);
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
if (!forbid_radical(bereg->NAME)) continue;
name=bereg->NAME;
bereg->NAME=getautoname(bereg->NAME);
addauthelem(HTABLE,name,(int)bereg->NAME);
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
if (!forbid_radical(bebux->NAME)) continue;
name=bebux->NAME;
bebux->NAME=getautoname(bebux->NAME);
addauthelem(HTABLE,name,(int)bebux->NAME);
}
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
changename(beaux->ABL);
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
changename(biabl->CNDABL);
changename(biabl->VALABL);
}
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) {
changename(biabl->CNDABL);
changename(biabl->VALABL);
}
}
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
changename(beout->ABL);
}
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) {
changename(biabl->CNDABL);
changename(biabl->VALABL);
}
}
/*free table*/
destroyauthtable(HTABLE);
HTABLE=NULL;
free_nameindex(); /*to save memory, we do not use these indexes later*/
}

View File

@ -0,0 +1,63 @@
/*
* 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 : BooG - change name signals
* Date : 2000
* Author : Francois Donnet
*/
#ifndef NORMALIZE_NAMEINDEX_H
#define NORMALIZE_NAMEINDEX_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/***************************************************************************/
/*if a vector has some space left between 2 bits, change vector in one to */
/*one bit no to corrupt befig */
/***************************************************************************/
extern void normalize_nameindex __P ((befig_list* befig));
/***************************************************************************/
/* some radical name can generate conflict with automatic indexation */
/*change name not to disturb algorithm */
/***************************************************************************/
extern void change_radical __P ((befig_list* befig));
/***************************************************************************/
/* sort vectors to be recognized by parser/driver */
/***************************************************************************/
extern void sort_vector __P ((befig_list* befig));
#endif

View File

@ -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 : BooG - 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 "bog_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*/
}

View File

@ -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 : BooG - 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

View File

@ -0,0 +1,266 @@
/*
* 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 : BooG - format flip-flop
* Date : 2000
* Author : Francois Donnet
*/
#include <stdlib.h>
#include <stdio.h>
#include <mut.h>
#include <abl.h>
#include <abe.h>
#include "bog_normalize_message.h"
#include "bog_signal_nameindex.h"
#include "bog_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, *save_ck=NULL;
biabl_list* biabl;
#if 0
chain_list* abl, *current;
chain_list *setup=NULL, *not_stable=NULL, *wen=NULL;
#endif
if (!bereg || !bereg->BIABL) {
fprintf(stderr,"identify_register: NULL pointer\n");
exit(1);
}
/*control all condition block*/
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
/*extract stable variable*/
ck=find_stable(biabl->CNDABL);
if (BEH_ERROR && save_ck) {
fprintf(stderr,
"BEH: Bad usage of stable for register %s\n",bereg->NAME);
return 0;
}
save_ck=ck;
if (ck) {/*for flip-flop memorize the clock setup signal*/
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;
}
/*memo clock name*/
biabl->USER=addptype(biabl->USER,ABL_STABLE,ck);
#if 0
/*separate clock setup value, stable and write enable*/
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)) {
setup=current;
}
else if (!ABL_ATOM(current) && ABL_OPER(current)==ABL_NOT
&& !ABL_ATOM(ABL_CADR(current))
&& ABL_OPER(ABL_CADR(current))==ABL_STABLE) {
not_stable=current;
}
else {
wen=current;
}
}
/*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;
}
freechain(biabl->CNDABL);
freeablexpr(not_stable);
if (!wen) biabl->CNDABL=setup;
else biabl->CNDABL=createablbinexpr(ABL_AND, wen, setup);
#endif
} /*end of flip-flop*/
} /*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*/
}
/******************************************************************************/
/* put back stable clock expression in condition register */
/******************************************************************************/
extern void put_back_STABLE(befig_list *befig)
{
#if 0
bereg_list* bereg;
ptype_list* ptype;
biabl_list* biabl;
char* ck;
chain_list* abl;
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
ptype=getptype(biabl->USER,ABL_STABLE);
if (!ptype) continue;
ck=(char*) ptype->DATA;
/*compare clock and setup value*/
if (!ABL_ATOM(biabl->CNDABL)) { /*not ck*/
abl=ABL_CADR(biabl->CNDABL);
if (!ABL_ATOM(abl) || ABL_OPER(biabl->CNDABL)!=ABL_NOT) {
fprintf(stderr,"BEH: error on condition register of %s\n",
bereg->NAME);
}
else {
if (ck!=ABL_ATOM_VALUE(abl)) { /* not mbk_not_ck=1 -> ck=1 */
ABL_ATOM_VALUE(abl)=getoppositename(ABL_ATOM_VALUE(abl));
freechain(biabl->CNDABL);
biabl->CNDABL=abl;
if (ck!=ABL_ATOM_VALUE(abl)) {
fprintf(stderr,"BEH: error on condition register of %s\n",
bereg->NAME);
}
}
}
}
else if (ABL_ATOM_VALUE(biabl->CNDABL)!=ck) { /* mbk_not_ck=1 */
ABL_ATOM_VALUE(biabl->CNDABL)=
getoppositename(ABL_ATOM_VALUE(biabl->CNDABL));
if (ck!=ABL_ATOM_VALUE(biabl->CNDABL)) { /* not ck = 1 */
fprintf(stderr,"BEH: error on condition register of %s\n",
bereg->NAME);
}
biabl->CNDABL=createablnotexpr(biabl->CNDABL);
}
/*add STABLE*/
abl=createabloper(ABL_STABLE);
ABL_CDR(abl)=addchain(NULL,createablatom(ck));
abl=createablnotexpr(abl);
biabl->CNDABL=createablbinexpr(ABL_AND,abl,biabl->CNDABL);
}
}
#endif
}

View File

@ -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 : BooG - 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));
/******************************************************************************/
/* put back stable clock expression in condition register */
/******************************************************************************/
extern void put_back_STABLE __P ((befig_list *befig));
#endif

View File

@ -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 : BooG - simplify befig expressions
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <abl.h>
#include <abe.h>
#include "bog_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);
}
}
}

View File

@ -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 : BooG - 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

View File

@ -0,0 +1,233 @@
/*
* 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 : BooG - count Capacitance
* Date : 2000
* Author : Francois Donnet
*/
#include <stdio.h>
#include <mut.h>
#include <abl.h>
#include <abe.h>
#include <aut.h>
#include <mlo.h>
#include "bog_lax_param.h"
#include "bog_lib_utils.h"
#include "bog_lib_negativ.h"
#include "bog_signal_utils.h"
#include "bog_signal_nameindex.h"
#include "bog_map_adapt.h"
#include "bog_signal_adapt.h"
/******************************************************************************/
/* do an average betwenn each values and its opposite */
/******************************************************************************/
extern void average_capacitance(befig_list *befig)
{
bereg_list* bereg;
bebux_list* bebux;
beaux_list* beaux;
bepor_list* bepor;
char* name;
float capa;
/*init*/
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
name=getoppositename(beaux->NAME);
capa=getcapacitance(beaux->NAME);
capa+=getcapacitance(name);
capa=capa/2;
putcapacitance(beaux->NAME,capa);
putcapacitance(name,capa);
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
name=getoppositename(bereg->NAME);
capa=getcapacitance(bereg->NAME);
capa+=getcapacitance(name);
capa=capa/2;
putcapacitance(bereg->NAME,capa);
putcapacitance(name,capa);
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
name=getoppositename(bebux->NAME);
capa=getcapacitance(bebux->NAME);
capa+=getcapacitance(name);
capa=capa/2;
putcapacitance(bebux->NAME,capa);
putcapacitance(name,capa);
}
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
/*inputs only*/
if (isvss(bepor->NAME) || isvdd(bepor->NAME)) continue;
switch (bepor->DIRECTION) {case OUT: case TRISTATE: continue;}
name=getoppositename(bepor->NAME);
capa=getcapacitance(bepor->NAME);
capa+=getcapacitance(name);
capa=capa/2;
putcapacitance(bepor->NAME,capa);
putcapacitance(name,capa);
}
}
/******************************************************************************/
/*calculate the capacitance for all signals */
/* change also form of abl to adapt to the biggest cell */
/******************************************************************************/
extern void adapt_for_cell(befig_list *befig)
{
beout_list* beout;
bebus_list* bebus;
bereg_list* bereg;
bebux_list* bebux;
beaux_list* beaux;
biabl_list* biabl;
bepor_list* bepor;
char* name;
/*constants*/
putcapacitance(getablatomone(),0);
putcapacitance(getablatomzero(),0);
/*init*/
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
name=getoppositename(beaux->NAME);
putcapacitance(beaux->NAME,0);
putcapacitance(name,0);
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
name=getoppositename(bereg->NAME);
putcapacitance(bereg->NAME,0);
putcapacitance(name,0);
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
name=getoppositename(bebux->NAME);
putcapacitance(bebux->NAME,0);
putcapacitance(name,0);
}
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
/*inputs only*/
if (isvss(bepor->NAME) || isvdd(bepor->NAME)) continue;
switch (bepor->DIRECTION) {case OUT: case TRISTATE: continue;}
name=getoppositename(bepor->NAME);
putcapacitance(bepor->NAME,0);
putcapacitance(name,0);
}
/*adapt abl for cell of library and eval capacitance*/
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
beout->ABL=inv_oper(beout->ABL,0); /*propagate NOT*/
beout->ABL=build_negativ(beout->ABL); /*minimize inverters*/
/*adapt the abl to match with a big cell later*/
beout->ABL=adapt_abl(beout->ABL); /*count capacitance of leaves*/
}
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
beaux->ABL=inv_oper(beaux->ABL,0); /*propagate NOT*/
beaux->ABL=build_negativ(beaux->ABL); /*minmize number of NOT*/
beaux->ABL=adapt_abl(beaux->ABL); /*count capacitance of leaves*/
}
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) {
biabl->VALABL=inv_oper(biabl->VALABL,0); /*propagate NOT*/
biabl->CNDABL=inv_oper(biabl->CNDABL,0); /*propagate NOT*/
biabl->VALABL=build_negativ(biabl->VALABL); /*minimize NOT*/
biabl->CNDABL=build_negativ(biabl->CNDABL);
}
bebus->BIABL=adapt_bus(bebus->BIABL); /*count capacitance of leaves*/
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
biabl->VALABL=inv_oper(biabl->VALABL,0); /*propagate NOT*/
biabl->CNDABL=inv_oper(biabl->CNDABL,0); /*propagate NOT*/
biabl->VALABL=build_negativ(biabl->VALABL); /*minimize NOT*/
biabl->CNDABL=build_negativ(biabl->CNDABL);
}
bereg->BIABL=adapt_reg(bereg->BIABL); /*count capacitance of leaves*/
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) {
biabl->VALABL=inv_oper(biabl->VALABL,0); /*propagate NOT*/
biabl->CNDABL=inv_oper(biabl->CNDABL,0); /*propagate NOT*/
biabl->VALABL=build_negativ(biabl->VALABL); /*minimize NOT*/
biabl->CNDABL=build_negativ(biabl->CNDABL);
}
bebux->BIABL=adapt_bus(bebux->BIABL); /*count capacitance of leaves*/
}
}
/******************************************************************************/
/* undefine all variables in hash table */
/******************************************************************************/
extern void undefine_delay(befig_list *befig)
{
bereg_list* bereg;
bebux_list* bebux;
beaux_list* beaux;
bepor_list* bepor;
/*init*/
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
undefdelay(beaux->NAME);
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
undefdelay(bereg->NAME);
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
undefdelay(bebux->NAME);
}
for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
/*inputs only*/
if (isvss(bepor->NAME) || isvdd(bepor->NAME)) continue;
switch (bepor->DIRECTION) {case OUT: case TRISTATE: continue;}
undefdelay(bepor->NAME);
}
}

View File

@ -0,0 +1,61 @@
/*
* 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 : BooG - count Capacitance
* Date : 2000
* Author : Francois Donnet
*/
#ifndef SIGNAL_ADAPT_H
#define SIGNAL_ADAPT_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/******************************************************************************/
/*calculate the capacitance for all signals */
/* change also form of abl to adapt to the biggest cell */
/******************************************************************************/
extern void adapt_for_cell __P ((befig_list *befig));
/******************************************************************************/
/* do an average betwenn each values and its opposite */
/******************************************************************************/
extern void average_capacitance __P ((befig_list *befig));
/******************************************************************************/
/* undefine all variables in hash table */
/******************************************************************************/
extern void undefine_delay __P ((befig_list *befig));
#endif

View File

@ -0,0 +1,351 @@
/*
* 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 : BooG - delay on signals
* Date : 2000
* Author : Francois Donnet
*/
#include <stdio.h>
#include <mut.h>
#include <abl.h>
#include <abe.h>
#include <aut.h>
#include <mlo.h>
#include "bog_lax_param.h"
#include "bog_lib_utils.h"
#include "bog_signal_utils.h"
#include "bog_signal_nameindex.h"
#include "bog_map_prepare.h"
#include "bog_map_pattern.h"
#include "bog_map_delay.h"
#include "bog_signal_delay.h"
/*to avoid warning*/
static void search_name(char* name, befig_list* befig);
/******************************************************************************/
/* return the max delay output for a befig */
/******************************************************************************/
static ptype_list* max_delay(befig_list* befig)
{
bereg_list* bereg;
bebus_list* bebus;
beout_list* beout;
float max_delay=-1;
float delay, ck;
char* name=NULL;
/*delay ot yet calculate for output*/
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
delay=loc_eval_delay(beout->ABL, getcapacitancelax(beout->NAME));
/*not to erase input values*/
putdelay(output_name(beout->NAME),delay);
if (delay>max_delay) {max_delay=delay; name=beout->NAME;}
}
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
delay=loc_eval_bus(bebus->BIABL,getcapacitancelax(bebus->NAME));
/*not to erase input values*/
putdelay(output_name(bebus->NAME),delay);
if (delay>max_delay) {max_delay=delay; name=bebus->NAME;}
}
/*calculate for register values*/
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
delay=eval_value_reg(bereg->BIABL);
ck=eval_clock_reg(bereg->BIABL);
/*not to erase input values*/
putdelay(output_name(bereg->NAME),delay);
delay-=ck; /*take care of ck setup time*/
if (delay>max_delay) {max_delay=delay; name=bereg->NAME;}
}
return addptype(NULL, (long)max_delay, name);
}
/***************************************************************************************/
/*return the list of local instances which are belonging to path */
/***************************************************************************************/
static ptype_list* search_long_path(loins_list* loins, befig_list* befig)
{
loins_list* loins_aux, *best_loins=NULL;
locon_list* locon;
losig_list* losig, *best_losig=NULL;
char* signame;
chain_list* loconchain;
ptype_list* ptype, *ret;
float max_delay=-1, delay;
bereg_list* bereg;
biabl_list* biabl;
if (!loins) {
fprintf(stderr,"search_long_path: NULL pointer\n");
exit(1);
}
/*seek the latest input in cell*/
for (locon=loins->LOCON; locon; locon=locon->NEXT) {
/*only inputs*/
if (locon->DIRECTION==OUT || locon->DIRECTION==TRISTATE
|| isvss(locon->NAME) || isvdd(locon->NAME)) continue;
losig=locon->SIG;
if (!losig->NAMECHAIN) {
fprintf(stderr,"search_long_path: NULL pointer\n");
exit(1);
}
signame=(char*) losig->NAMECHAIN->DATA;
delay=getdelay(signame);
if (delay>max_delay) {
best_losig=losig;
max_delay=delay;
}
}
/*no input found -> constant*/
if (!best_losig) return NULL;
losig=best_losig;
ptype=getptype(losig->USER,LOFIGCHAIN);
if (!ptype || !ptype->DATA) {
fprintf(stderr,"search_long_path: NULL pointer\n");
exit(1);
}
signame=(char*) losig->NAMECHAIN->DATA;
ret=addptype(NULL, (int) max_delay, signame);
/*stop at leaves or flip-flop */
if (losig->TYPE==EXTERNAL) return ret;
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
if (bereg->NAME!=signame) continue;
/*is it a flip-flop?*/
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
if (getptype(biabl->USER,ABL_STABLE)) return ret;
}
}
/*search driver of signal (latest if bus)*/
max_delay=-1;
for (loconchain=(chain_list*) ptype->DATA; loconchain; loconchain=loconchain->NEXT) {
locon=(locon_list*) loconchain->DATA;
/*only outputs*/
if (locon->DIRECTION==IN || isvss(locon->NAME) || isvdd(locon->NAME)
|| locon->TYPE==EXTERNAL) continue;
loins_aux=locon->ROOT;
if (loins_aux==loins) continue;
delay=getdelay(loins_name(loins_aux->INSNAME));
if (delay>max_delay) {
best_loins=loins_aux;
max_delay=delay;
}
}
if (!best_loins) {
fprintf(stderr,"search_long_path: no loins found for driving losig '%s'\n",signame);
exit(1);
}
ret->NEXT=search_long_path(best_loins, befig);
return ret;
}
/******************************************************************************/
/* latest delay path */
/*return list of signals in critical path. PTYPE is delay on signal */
/*if return NULL, no path has been found */
/******************************************************************************/
extern ptype_list* max_delay_path(befig_list* befig, lofig_list* lofig)
{
ptype_list* head, *path;
loins_list* loins;
if (!befig) {
fprintf(stderr,"max_delay_path: NULL pointer\n");
exit(1);
}
if (!lofig->LOINS) return NULL;
head=max_delay(befig);
if (head) {
/*search instance which begins*/
for (loins=lofig->LOINS; loins; loins=loins->NEXT) {
if ((char*) head->DATA==loins->INSNAME) break;
}
if (!loins) {
fprintf(stderr,"max_delay_path: no loins '%s' found\n",(char*) head->DATA);
exit(1);
}
path=search_long_path(loins, befig);
head->NEXT=path;
}
return (ptype_list*) reverse((chain_list*)head);
}
/***************************************************************************/
/* eval the delay of each abl variables */
/***************************************************************************/
static void search_abl(chain_list* abl, befig_list* befig)
{
if (!abl) {
fprintf(stderr,"search_abl: NULL pointer\n");
exit(1);
}
if (!ABL_ATOM(abl)) { /*operator*/
for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) {
search_abl(ABL_CAR(abl),befig);
}
return;
}
if (isdelaydefined(ABL_ATOM_VALUE(abl))) return;
search_name(ABL_ATOM_VALUE(abl),befig);
}
/******************************************************************************/
/*search a signal and define its delay */
/******************************************************************************/
static void search_name(char* name, befig_list* befig)
{
bereg_list* bereg;
beaux_list* beaux;
bebux_list* bebux;
biabl_list* biabl;
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
if (beaux->NAME!=name) continue;
search_abl(beaux->ABL,befig);
eval_delay(beaux->NAME,beaux->ABL);
return;
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
if (bebux->NAME!=name) continue;
for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) {
search_abl(biabl->CNDABL,befig);
search_abl(biabl->VALABL,befig);
}
eval_bus(bebux->NAME,bebux->BIABL);
return;
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
if (bereg->NAME!=name) continue;
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
search_abl(biabl->CNDABL,befig); /*only condition*/
if (!getptype(biabl->USER,ABL_STABLE)) { /*only latch*/
search_abl(biabl->VALABL,befig);
}
}
/*calculate delay on clock setup for flip-flop and on all entries */
/*for latch*/
eval_reg(bereg->NAME,bereg->BIABL);
return;
}
fprintf(stderr,"search_name: %s unknown\n",name);
exit(1);
}
/***************************************************************************/
/*global delay estimation on internal signals */
/***************************************************************************/
extern void final_eval_delay(befig_list *befig)
{
bereg_list *bereg;
bebus_list *bebus;
beout_list *beout;
biabl_list *biabl;
bepor_list* bepor;
float delay;
if (!befig) {
fprintf(stderr,"eval_delay: NULL pointer\n");
exit(1);
}
/*constants*/
putdelay(getablatomone(),0);
putdelay(getablatomzero(),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;
/* T + RC */
delay=getdelaylax(bepor->NAME) + getimpedancelax(bepor->NAME)
* getcapacitance(bepor->NAME);
putdelay(bepor->NAME,delay);
}
/*separ value from condition for flip-flop to avoid cycle*/
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
if (getptype(biabl->USER,ABL_STABLE)) { /*only flip-flop*/
search_abl(biabl->VALABL,befig);
}
}
}
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
search_abl(beout->ABL,befig);
/*do not define delay now*/
}
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) {
search_abl(biabl->CNDABL,befig);
search_abl(biabl->VALABL,befig);
/*do not define delay now*/
}
}
}

View File

@ -0,0 +1,59 @@
/*
* 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 : BooG - count Capacitance
* Date : 2000
* Author : Francois Donnet
*/
#ifndef SIGNAL_SIG_DELAY_H
#define SIGNAL_SIG_DELAY_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/***************************************************************************/
/*global delay estimation on internal signals */
/***************************************************************************/
extern void final_eval_delay __P ((befig_list *befig));
/******************************************************************************/
/* latest delay path */
/* return 2 elements the first is the name of input and the second is the naem*/
/* of the output. */
/*if return NULL, no path has been found */
/******************************************************************************/
extern ptype_list* max_delay_path __P ((befig_list* befig, lofig_list* lofig));
#endif

View File

@ -0,0 +1,218 @@
/*
* 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 : BooG - give unique index
* Date : 2000
* Author : Francois Donnet
*/
#include <string.h>
#include <mut.h>
#include <abl.h>
#include <aut.h>
#include <abe.h>
#include "bog_lib_utils.h"
#include "bog_lib_cell.h"
#include "bog_signal_nameindex.h"
#define MBK_NOT namealloc("MBK_NOT")
#define MBK_SIG namealloc("MBK_SIG")
#define MBK_OUT namealloc("MBK_OUT")
#define MBK_INS namealloc("MBK_INS")
#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 1 if radical name can generate conflict with automatic indexation*/
/***************************************************************************/
extern int forbid_radical(char* name)
{
int size;
cell_list *cell;
name=vectorradical(name);
/*control first if it is the negation itself*/
size=strlen(MBK_NOT);
if (strlen(name)>=size && !strncmp(name,MBK_NOT,size)) return 1;
/*control with the names of library*/
for (cell=getcell_logic_lib(); cell; cell=cell->NEXT) {
size=strlen(cell->NAME);
if (strlen(name)>=size && !strncmp(name,cell->NAME,size)) return 1;
}
for (cell=getcell_tristate_lib(); cell; cell=cell->NEXT) {
size=strlen(cell->NAME);
if (strlen(name)>=size && !strncmp(name,cell->NAME,size)) return 1;
}
for (cell=getcell_register_lib(); cell; cell=cell->NEXT) {
size=strlen(cell->NAME);
if (strlen(name)>=size && !strncmp(name,cell->NAME,size)) return 1;
}
return 0; /*no conflict*/
}
/***************************************************************************/
/* 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 opposite name */
/******************************************************************************/
extern char* getoppositename(char* name)
{
char memo_char;
int size;
name=namealloc(name);
/*constant 1 0*/
if (name==getablatomone()) return getablatomzero();
if (name==getablatomzero()) return getablatomone();
/*control first if it is the negation itself*/
size=strlen(MBK_NOT);
if (!strncmp(name,MBK_NOT,size)) {
name=name+size+1; /* separator "_" */
return namealloc(name);
}
memo_char=SEPAR; /*external value from MBK environment*/
SEPAR='_';
name=concatname(MBK_NOT,name);
SEPAR=memo_char;
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_SIG,name);
SEPAR=memo_char;
return getnameindex(name);
}
/******************************************************************************/
/* return an artificial name to distinguish loins from signal */
/* only used to hash values for internal treatment */
/******************************************************************************/
extern char* loins_name(char* name)
{
char memo_char;
name=namealloc(name);
memo_char=SEPAR; /*external value from MBK environment*/
SEPAR='_';
name=concatname(MBK_INS,name);
SEPAR=memo_char;
return name;
}
/******************************************************************************/
/* return an artificial name to distinguish input datas from output datas in */
/* the case of inout port */
/* only used to hash values for internal treatment */
/******************************************************************************/
extern char* output_name(char* name)
{
char memo_char;
name=namealloc(name);
memo_char=SEPAR; /*external value from MBK environment*/
SEPAR='_';
name=concatname(MBK_SIG,name);
name=concatname(MBK_OUT,name);
SEPAR=memo_char;
return name;
}

View File

@ -0,0 +1,85 @@
/*
* 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 : BooG - give unique index
* Date : 2000
* Author : Francois Donnet
*/
#ifndef SIGNAL_NAMEINDEX_H
#define SIGNAL_NAMEINDEX_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 1 if radical name can generate conflict with automatic indexation*/
/***************************************************************************/
extern int forbid_radical __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 free_nameindex() below */
/***************************************************************************/
extern char* getnameindex __P ((char* name));
/******************************************************************************/
/* build a generic opposite name */
/******************************************************************************/
extern char* getoppositename __P ((char* name));
/******************************************************************************/
/* build a generic name with an incremented index */
/******************************************************************************/
extern char* getautoname __P ((char* name));
/******************************************************************************/
/* return an artificial name to distinguish loins from signal */
/* only used to hash values for internal treatment */
/******************************************************************************/
extern char* loins_name __P ((char* name));
/******************************************************************************/
/* return an artificial name to distinguish input datas from output datas in */
/* the case of inout port */
/* only used to hash values for internal treatment */
/******************************************************************************/
extern char* output_name __P ((char* name));
#endif

View File

@ -0,0 +1,382 @@
/*
* 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 : BooG - signals table
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <abl.h>
#include <abe.h>
#include <aut.h>
#include "bog_lax_param.h"
#include "bog_signal_utils.h"
/*size of memory block*/
#define BLOCK 2048
typedef struct signal{
struct signal* NEXT;
beaux_list* BEAUX; /*only for beaux signals*/
float T; /*every float because they will be divided later*/
float C;
char DELAY_SET; /*flag put to 1 if DELAY is defined*/
} 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->BEAUX=NULL;
new->C=DEFAULT_CAPACITANCE;
new->T=DEFAULT_DELAY;
new->DELAY_SET=0; /*delay not defined yet*/
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);
}
/***************************************************************************/
/*remove a signal from htable */
/***************************************************************************/
extern void delsignal(char *name)
{
if (!name) {
fprintf(stderr,"delsignal: no name\n");
exit(1);
}
/*if doesn't exist hash table, init*/
if (!HTABLE) init_signals();
delauthelem(HTABLE,name);
}
/***************************************************************************/
/* 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;
}
/***************************************************************************/
/*return non-zero if signal exists */
/***************************************************************************/
extern int is_signal(char* name)
{
if (!name) {
fprintf(stderr,"is_signal: no name\n");
exit(1);
}
/*if doesn't exist hash table, init*/
if (!HTABLE) init_signals();
return searchauthelem(HTABLE,name) != NULL;
}
/***************************************************************************/
/* put a delay to a signal */
/***************************************************************************/
extern void putdelay(char* name, float 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->DELAY_SET=1; /*delay is defined*/
signal->T=delay;
if (signal->T<0) signal->T=0;
}
/***************************************************************************/
/* return the signal delay */
/***************************************************************************/
extern float 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, float delay)
{
signal_list* signal;
if (!name) {
fprintf(stderr,"incdelay: no name\n");
exit(1);
}
signal=getsignal(name,0);
signal->T+=delay;
signal->DELAY_SET=1; /*delay is defined*/
if (signal->T<0) signal->T=0;
}
/***************************************************************************/
/* return 1 if the delay for signal name is defined */
/***************************************************************************/
extern int isdelaydefined(char* name)
{
signal_list* signal;
if (!name) {
fprintf(stderr,"isdelaydefined: no name\n");
exit(1);
}
signal=getsignal(name,0/*if doesn't exist then error*/);
return signal->DELAY_SET;
}
/***************************************************************************/
/* undefine the delay */
/***************************************************************************/
extern void undefdelay(char* name)
{
signal_list* signal;
if (!name) {
fprintf(stderr,"undefdelay: no name\n");
exit(1);
}
signal=getsignal(name,0/*if doesn't exist then error*/);
signal->DELAY_SET=0;
}
/******************************************************************************/
/* return the signal beaux */
/******************************************************************************/
extern beaux_list* getbeaux(char* name)
{
signal_list* signal;
if (!name) {
fprintf(stderr,"getbeaux: no name\n");
exit(1);
}
signal=getsignal(name,0/*if doesn't exist then error*/);
return signal->BEAUX;
}
/******************************************************************************/
/* put a beaux to a signal */
/******************************************************************************/
extern void putbeaux(char* name, beaux_list* beaux)
{
signal_list* signal;
if (!name) {
fprintf(stderr,"putbeaux: no name\n");
exit(1);
}
signal=getsignal(name,0/*if doesn't exist create it*/);
signal->BEAUX=beaux;
}
/***************************************************************************/
/* return the signal capacitance */
/***************************************************************************/
extern float 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, float 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, float 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;
}

View File

@ -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 : BooG - 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
/***************************************************************************/
/*return non-zero if signal exists */
/***************************************************************************/
extern int is_signal __P ((char* name));
/***************************************************************************/
/*remove a signal from htable */
/***************************************************************************/
extern void delsignal __P ((char *name));
/***************************************************************************/
/* 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, float delay));
/***************************************************************************/
/* return the signal delay (local hash table) */
/***************************************************************************/
extern float getdelay __P ((char* name));
/***************************************************************************/
/* add a delay to a signal */
/***************************************************************************/
extern void incdelay __P ((char* name, float delay));
/***************************************************************************/
/* return 1 if the delay for signal name is defined */
/***************************************************************************/
extern int isdelaydefined __P ((char* name));
/***************************************************************************/
/* undefine the delay */
/***************************************************************************/
extern void undefdelay __P ((char* name));
/******************************************************************************/
/* return the signal beaux */
/******************************************************************************/
extern beaux_list* getbeaux __P ((char* name));
/******************************************************************************/
/* put a beaux to a signal */
/******************************************************************************/
extern void putbeaux __P ((char* name, beaux_list* beaux));
/***************************************************************************/
/* return the signal capacitance */
/***************************************************************************/
extern float getcapacitance __P ((char* name));
/***************************************************************************/
/* add a capacitance to a signal */
/***************************************************************************/
extern void inccapacitance __P ((char* name, float capacitance));
/***************************************************************************/
/* put a capacitance to a signal */
/***************************************************************************/
extern void putcapacitance __P ((char* name, float capacitance));
#endif

View File

@ -0,0 +1,108 @@
/*
* 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 : BooG - unflatten an abl
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <mlo.h>
#include <abl.h>
#include <abe.h>
#include "bog_signal_nameindex.h"
#include "bog_normalize_ARITY.h"
#include "bog_lib_utils.h"
#include "bog_lib_complete.h"
#include "bog_signal_utils.h"
#include "bog_unflatten_utils.h"
#include "bog_unflatten_oper.h"
#include "bog_unflatten_abl.h"
/***************************************************************************/
/* unflatten each oper of abl */
/***************************************************************************/
static input_list* unflatten_each_oper(chain_list* abl)
{
chain_list* chain;
input_list* new, *inputs=NULL;
char* name, *opposite;
int oper;
/*for leaf build also opposite*/
if (ABL_ATOM(abl)) {
name=ABL_ATOM_VALUE(abl);
opposite=getoppositename(name);
new=newinput();
new->ABL=abl;
new->NEG_ABL=createablatom(opposite);
new->DELAY=getdelay(name);
new->NEG_DELAY=getdelay(opposite);
new->R=0;
new->NEG_R=0;
return new;
}
/*buid a list of inputs for algorithm*/
for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
new=unflatten_each_oper(ABL_CAR(chain));
/*sort from the shortest to the longest delay*/
inputs=sort_input(inputs,new);
}
oper=ABL_OPER(abl);
freechain(abl);
return unflatten_oper(oper, inputs);
}
/***************************************************************************/
/* unflatten an abl to match with the cell library */
/* optimize in delay or in area depending of .lax file */
/***************************************************************************/
extern chain_list* unflatten_abl(chain_list* abl)
{
input_list* input;
if (!abl) {
fprintf(stderr,"unflatten_abl: NULL pointer\n");
exit(1);
}
/*return the cone head and the opposite value with their delays*/
input=unflatten_each_oper(abl);
abl=input->ABL;
input->ABL=NULL; /*protect from freeinput() */
freeinput(input);
put_arity_abl(abl);
return abl;
}

View File

@ -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 : BooG - unflatten an abl
* Date : 2000
* Author : Francois Donnet
*/
#ifndef UNFLATTEN_ABL_H
#define UNFLATTEN_ABL_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/***************************************************************************/
/* unflatten an abl to match with the cell library */
/* optimize in delay or in area depending of .lax file */
/***************************************************************************/
extern chain_list* unflatten_abl __P ((chain_list* abl));
#endif

View File

@ -0,0 +1,230 @@
/*
* 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 : BooG - unflatten with optimize in area
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <mlo.h>
#include <abl.h>
#include <abe.h>
#include "bog_normalize_ARITY.h"
#include "bog_normalize_message.h"
#include "bog_lib_utils.h"
#include "bog_lib_cell.h"
#include "bog_lib_complete.h"
#include "bog_unflatten_utils.h"
#include "bog_unflatten_oper.h"
#include "bog_unflatten_area.h"
/***************************************************************************/
/* cost is the number of inputs left if we map all entries with this cell */
/* for first level of tree */
/*====> cost = size/arity + rest */
/***************************************************************************/
static note_list* eval_note(note_list* all_note, cell_list* cell, input_list *entry, int size)
{
port_list* port;
note_list* note;
float latest=0, delay, R=0;
int source_positiv, dest_positiv, cost;
chain_list* portchain;
/*operator too big*/
if (size<ABL_ARITY(cell->ABL)) return all_note;
source_positiv=is_source_positiv(ABL_OPER(cell->ABL));
dest_positiv=is_dest_positiv(ABL_OPER(cell->ABL),ABL_ARITY(cell->ABL));
/*operator no matches*/
if (source_positiv==-1 || dest_positiv==-1) return all_note;
/*eval cost */
cost=size/ABL_ARITY(cell->ABL)+size%ABL_ARITY(cell->ABL);
/*search if there is already a couple of this arity*/
for (note=all_note; note; note=note->NEXT) {
if (note->ARITY==ABL_ARITY(cell->ABL)) {
/*if worse than last record, skip it*/
if (dest_positiv) {
if (cost>note->COST) return all_note;
}
else if (cost>note->NEG_COST) return all_note;
break;
}
}
/*eval delay*/
for (portchain=ABL_CDR(cell->ABL); portchain; portchain=portchain->NEXT) {
port=(port_list*) ABL_ATOM_VALUE(ABL_CAR(portchain));
delay=port->T;
delay+=source_positiv?entry->DELAY:entry->NEG_DELAY;
/*sortance=1*/
delay+= port->C * (source_positiv?entry->R:entry->NEG_R);
if (delay>latest) {latest=delay; R=port->R;}
if (note) {
/*if worse than last record, skip it*/
if (dest_positiv) {
if (latest>=note->DELAY) return all_note;
}
else if (latest>=note->NEG_DELAY) return all_note;
}
entry=entry->NEXT;
}
/*create a new couple if doesn't exist*/
if (!note) {
note=newnote();
note->NEXT=all_note;
all_note=note;
note->ARITY=ABL_ARITY(cell->ABL);
}
/*take new solution*/
if (dest_positiv) {
note->DELAY=latest;
note->R=R;
note->COST=cost;
note->CELL=cell;
}
else {
note->NEG_DELAY=latest;
note->NEG_R=R;
note->NEG_COST=cost;
note->NEG_CELL=cell;
}
return all_note;
}
/***************************************************************************/
/* unflatten to improve area */
/* insert a cell to produce the most equilibrated tree */
/* return the new list of entry after insertion */
/* if no cell can satisfy condition result the entry list unchanged */
/***************************************************************************/
extern input_list* unflatten_area(input_list *entry, int entry_number)
{
input_list *pred = NULL, *input, *new_input;
chain_list* abl;
cell_list* cell;
note_list* note, *all_note=NULL, *best_note;
int cell_source_positiv, neg_cell_source_positiv; /*flag*/
if (!entry) {
fprintf(stderr,"unflatten_area: no input\n");
exit(1);
}
/*test all the simple logic library*/
for (cell=getcell_oper_lib(); cell; cell=cell->NEXT) {
all_note=eval_note(all_note, cell, entry, entry_number);
}
/*no result pattern, impossible to map, signal it to caller function*/
if (!all_note) return entry;
/*take the best for a positiv and negativ results*/
best_note=all_note;
best_note->AVERAGE_COST=(best_note->COST+best_note->NEG_COST)/2;
for (note=all_note->NEXT; note; note=note->NEXT) {
note->AVERAGE_COST=(note->COST+note->NEG_COST)/2;
if (note->AVERAGE_COST<best_note->AVERAGE_COST) best_note=note;
else if (note->AVERAGE_COST==best_note->AVERAGE_COST
&& note->ARITY>best_note->ARITY) best_note=note;
else if (note->AVERAGE_COST==best_note->AVERAGE_COST
&& note->ARITY==best_note->ARITY
&& note->DELAY+note->NEG_DELAY<best_note->DELAY+best_note->NEG_DELAY)
best_note=note;
}
/*one of those cells are missing, impossible to unflat*/
if (!best_note->CELL || !best_note->NEG_CELL) {
fprintf(stderr,
"unflatten_area: opposite cell of %s is missing (%d inputs)\n",
best_note->CELL?best_note->CELL->NAME:best_note->NEG_CELL->NAME,
entry_number);
exit(1);
}
/*build new input*/
new_input=newinput();
new_input->DELAY=best_note->DELAY;
new_input->NEG_DELAY=best_note->NEG_DELAY;
new_input->R=best_note->R;
new_input->NEG_R=best_note->NEG_R;
new_input->ABL=createabloper(ABL_OPER(best_note->CELL->ABL));
new_input->NEG_ABL=createabloper(ABL_OPER(best_note->NEG_CELL->ABL));
cell_source_positiv=is_source_positiv(ABL_OPER(best_note->CELL->ABL));
neg_cell_source_positiv=is_source_positiv(
ABL_OPER(best_note->NEG_CELL->ABL)); /*put operands*/
for (input=entry; input; input=input->NEXT) {
if (best_note->ARITY==0) break;
best_note->ARITY--;
/*positiv*/
if (cell_source_positiv) {
abl=input->ABL;
input->ABL=NULL; /* protect from freeinput() */
}
else {
abl=input->NEG_ABL;
input->NEG_ABL=NULL; /* protect from freeinput() */
}
ABL_CDR(new_input->ABL)=addchain(ABL_CDR(new_input->ABL),abl);
/*opposite*/
if (neg_cell_source_positiv) {
if (input->ABL) abl=input->ABL;
else abl=dupablexpr(abl); /*already used above*/
input->ABL=NULL; /* protect from freeinput() */
}
else {
if (input->NEG_ABL) abl=input->NEG_ABL;
else abl=dupablexpr(abl); /*already used above*/
input->NEG_ABL=NULL; /* protect from freeinput() */
}
ABL_CDR(new_input->NEG_ABL)=addchain(ABL_CDR(new_input->NEG_ABL),abl);
pred=input;
}
pred->NEXT=NULL;
freeinput(entry);
freenote(all_note);
return sort_input(input,new_input); /*return a sort list*/
}

View File

@ -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 : BooG - unflatten with optimize in area
* Date : 2000
* Author : Francois Donnet
*/
#ifndef UNFLATTEN_AREA_H
#define UNFLATTEN_AREA_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/***************************************************************************/
/* unflatten to improve area */
/* insert a cell to produce the most equilibrated tree */
/* return the new list of inputs after insertion */
/* if no cell can satisfy condition result the entry list unchanged */
/***************************************************************************/
extern input_list* unflatten_area __P ((input_list *inputs, int entry_number));
#endif

View File

@ -0,0 +1,352 @@
/*
* 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 : BooG - unflatten a befig
* Date : 2000
* Author : Francois Donnet
*/
#include <stdio.h>
#include <mut.h>
#include <mlo.h>
#include <abl.h>
#include <abe.h>
#include <aut.h>
#include "bog_lax_param.h"
#include "bog_lib_utils.h"
#include "bog_lib_cell.h"
#include "bog_map_pattern.h"
#include "bog_normalize_ARITY.h"
#include "bog_signal_nameindex.h"
#include "bog_map_adapt.h"
#include "bog_map_delay.h"
#include "bog_unflatten_abl.h"
#include "bog_signal_utils.h"
#include "bog_unflatten_befig.h"
static befig_list *befig; /*the figure to check*/
/*to avoid warning during compiling*/
static void search_name(char* name);
/******************************************************************************/
/* change all leaf expressions from 'mbk_not_a' to 'NOT (a)' */
/******************************************************************************/
static chain_list* change_atom(chain_list* abl,int invert)
{
chain_list* chain;
if (ABL_ATOM(abl)) {
if (!invert) return abl;
ABL_ATOM_VALUE(abl)=getoppositename(ABL_ATOM_VALUE(abl));
return createablnotexpr(abl);
}
switch (ABL_OPER(abl)) {
case ABL_NAND: case ABL_NOR: case ABL_NOT: invert=1; break;
default: invert=0;
}
for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
ABL_CAR(chain)=change_atom(ABL_CAR(chain),invert);
}
return abl;
}
/***************************************************************************/
/*create the opposite beaux of name */
/***************************************************************************/
extern beaux_list* build_inv_name(char *name)
{
chain_list* abl;
abl=createablnotexpr(createablatom(name));
put_arity_abl(abl);
befig->BEAUX=
beh_addbeaux(befig->BEAUX,getoppositename(name),abl,NULL);
return befig->BEAUX;
}
/***************************************************************************/
/*create the opposite of beaux */
/***************************************************************************/
static beaux_list* build_inv_beaux(beaux_list *beaux)
{
chain_list* abl;
/*create inverted value abl*/
if (ABL_ATOM(beaux->ABL)) {
abl=createablatom(getoppositename(ABL_ATOM_VALUE(beaux->ABL)));
}
else if (getoptimlax()>=OPTIM_DELAY4) {
abl=createablnotexpr(dupablexpr(beaux->ABL));
abl=unflatten_abl(abl);
}
else if (getoptimlax()<=OPTIM_DELAY1) {
abl=createablnotexpr(createablatom(beaux->NAME));
}
else {
#if 0
char *signame;
cell_list* cell;
port_list* port, *top;
int only_atom=1;
/*search cell which matches*/
cell=cell_pattern(beaux->ABL);
top=copyport(cell->PORT); /*can be used by eval_delay()*/
/*build auxiliary signal to put in common use with opposite*/
for (port=top; port; port=port->NEXT) {
if (isvss(port->NAME) || isvdd(port->NAME)) continue;
else switch (port->DIRECTION) {
case OUT: case TRISTATE: break;
default:
if (!port->ABL) {
fprintf(stderr,
"build_inv_beaux: compute error %s not really match on port %s\n",
cell->NAME,port->NAME);
exit(1);
}
/*if already a signal no use to build a new one*/
if (ABL_ATOM(port->ABL)) break;
only_atom=0;
/*create an auxiliary signal*/
signame=getautoname(beaux->NAME);
/*swap pointers references*/
abl=createablatom(signame);
swap_pointers(port->ABL,abl); /*abl is port->ABL, port->ABL is abl*/
/*create commun leaves*/
putcapacitance(signame,port->C*2/*the other cell*/);
befig->BEAUX=beh_addbeaux(befig->BEAUX,signame,abl,NULL);
eval_delay(befig->BEAUX->NAME,befig->BEAUX->ABL);
}
}
delport(top);
/*create opposite beaux*/
abl=createablnotexpr(dupablexpr(beaux->ABL));
/* mbk_not_a ------> NOT (a) (NOT will be absorbed by oper ahead) */
if (only_atom) change_atom(abl,1);
#else
abl=createablnotexpr(createablatom(beaux->NAME));
#endif
}
put_arity_abl(abl);
/*new cell*/
befig->BEAUX=
beh_addbeaux(befig->BEAUX,getoppositename(beaux->NAME),abl,NULL);
return befig->BEAUX;
}
/***************************************************************************/
/* eval the delay of each abl variables */
/***************************************************************************/
static void search_abl(chain_list* abl)
{
if (!abl) {
fprintf(stderr,"search_abl: NULL pointer\n");
exit(1);
}
if (!ABL_ATOM(abl)) { /*operator*/
for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) {
search_abl(ABL_CAR(abl));
}
return;
}
if (isdelaydefined(ABL_ATOM_VALUE(abl))) return;
search_name(ABL_ATOM_VALUE(abl));
}
/******************************************************************************/
/*search a signal and define its delay */
/* unflatten the expression of this signal */
/******************************************************************************/
static void search_name(char* name)
{
bereg_list* bereg;
beaux_list* beaux, *new_beaux;
bebux_list* bebux;
biabl_list* biabl;
beaux=getbeaux(name); /*used only by beaux*/
if (beaux) {
search_abl(beaux->ABL); /*define first leaves*/
beaux->ABL=unflatten_abl(beaux->ABL);
/*recount Capacitance of leaves*/
new_beaux=build_inv_beaux(beaux);
eval_delay(new_beaux->NAME,new_beaux->ABL);
eval_delay(beaux->NAME,beaux->ABL);
return;
}
for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) {
if (bebux->NAME==name || getoppositename(bebux->NAME)==name) {
for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) {
search_abl(biabl->CNDABL);
search_abl(biabl->VALABL);
/*check if there is a tristate inverter in library*/
/* keep the NOT to use inverter bus */
if (is_tristate_inverter_lib() &&
!ABL_ATOM(biabl->VALABL) && ABL_OPER(biabl->VALABL)==ABL_NOT) {
ABL_CADR(biabl->VALABL)=unflatten_abl(ABL_CADR(biabl->VALABL));
}
else biabl->VALABL=unflatten_abl(biabl->VALABL); /*arity solver*/
biabl->CNDABL=unflatten_abl(biabl->CNDABL); /*arity solver*/
}
/*recount Capacitance of leaves*/
eval_bus(bebux->NAME,bebux->BIABL);
/*evaluate opposite value delay*/
new_beaux=build_inv_name(bebux->NAME);
eval_delay(new_beaux->NAME,new_beaux->ABL);
return;
}
}
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
if (bereg->NAME==name || getoppositename(bereg->NAME)==name) {
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
search_abl(biabl->CNDABL); /*only condition*/
if (!getptype(biabl->USER,ABL_STABLE)) { /*only latch*/
biabl->CNDABL=unflatten_abl(biabl->CNDABL); /*arity solver*/
search_abl(biabl->VALABL);
biabl->VALABL=unflatten_abl(biabl->VALABL); /*arity solver*/
/*recount Capacitance of leaves only for latch*/
}
}
/*calculate delay on clock setup for flip-flop and on all entries */
/*for latch*/
eval_reg(bereg->NAME,bereg->BIABL);
/*evaluate opposite value delay*/
new_beaux=build_inv_name(bereg->NAME);
eval_delay(new_beaux->NAME,new_beaux->ABL);
return;
}
}
fprintf(stderr,"search_name: %s unknown\n",name);
exit(1);
}
/***************************************************************************/
/* estimate delay and change abl structure to match cell library and */
/* optimize either circuit size or circuit delay */
/***************************************************************************/
extern void unflatten_befig(befig_list *befig_param)
{
beaux_list* beaux, *new_beaux;
bereg_list *bereg;
bebus_list *bebus;
beout_list *beout;
biabl_list *biabl;
bepor_list* bepor;
float delay;
if (!befig_param) {
fprintf(stderr,"delay_multigraph: NULL pointer\n");
exit(1);
}
befig=befig_param;
/*to fasten search because of hash table*/
for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) {
putbeaux(beaux->NAME,beaux); /*put in hash table for quick search*/
/*invert value refers to the same abl*/
putbeaux(getoppositename(beaux->NAME),beaux);
}
/*constants*/
putdelay(getablatomone(),0);
putdelay(getablatomzero(),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;
/* T + RC */
delay=getdelaylax(bepor->NAME) + getimpedancelax(bepor->NAME)
* getcapacitance(bepor->NAME);
putdelay(bepor->NAME,delay);
/*evaluate opposite value delay*/
new_beaux=build_inv_name(bepor->NAME);
eval_delay(new_beaux->NAME,new_beaux->ABL);
}
/*separ value from condition for flip-flop to avoid cycle*/
for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) {
for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) {
if (getptype(biabl->USER,ABL_STABLE)) { /*only flip-flop*/
search_abl(biabl->VALABL);
biabl->VALABL=unflatten_abl(biabl->VALABL); /*arity solver*/
/*recount Capacitance of leaves*/
}
}
}
for (beout=befig->BEOUT; beout; beout=beout->NEXT) {
search_abl(beout->ABL);
beout->ABL=unflatten_abl(beout->ABL); /*arity solver*/
}
for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) {
for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) {
search_abl(biabl->CNDABL);
search_abl(biabl->VALABL);
/*check if there is a tristate inverter in library*/
/* keep the NOT to use inverter bus */
if (is_tristate_inverter_lib() &&
!ABL_ATOM(biabl->VALABL) && ABL_OPER(biabl->VALABL)==ABL_NOT) {
ABL_CADR(biabl->VALABL)=unflatten_abl(ABL_CADR(biabl->VALABL));
}
else biabl->VALABL=unflatten_abl(biabl->VALABL); /*arity solver*/
biabl->CNDABL=unflatten_abl(biabl->CNDABL); /*arity solver*/
}
}
}

View File

@ -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 : BooG - unflatten a befig
* Date : 2000
* Author : Francois Donnet
*/
#ifndef UNFLATTEN_BEFIG_H
#define UNFLATTEN_BEFIG_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/***************************************************************************/
/* estimate delay and change abl structure to match cell library and */
/* optimize either circuit size or circuit delay */
/***************************************************************************/
extern void unflatten_befig __P ((befig_list *befig_param));
#endif

View File

@ -0,0 +1,239 @@
/*
* 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 : BooG - unflatten with optimized delay
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <mlo.h>
#include <abl.h>
#include <abe.h>
#include "bog_normalize_ARITY.h"
#include "bog_lib_utils.h"
#include "bog_lib_cell.h"
#include "bog_lib_complete.h"
#include "bog_unflatten_utils.h"
#include "bog_unflatten_oper.h"
#include "bog_unflatten_delay.h"
/***************************************************************************/
/*the cost is the place of the new output in the rest of entry */
/*====> example: operator is AND_3=1.1 ps */
/*and entry are a=3.0(used) b=4.2(used) c=6.0(used) d=7.0 e=7.2 f=9 ps */
/*====> X=7.1 cost(X)=2 because X arrives after d but before e and f */
/*====> X=9.5 no solution given by this algorithm */
/***************************************************************************/
static note_list* eval_note(note_list* all_note, cell_list* cell, input_list *entry, int size, input_list* last_input)
{
port_list* port;
note_list* note;
float latest=0, delay, R=0;
int source_positiv, dest_positiv, cost;
chain_list* portchain;
/*operator too big or match completely(this algorithm do not work)*/
if (size<=ABL_ARITY(cell->ABL)) return all_note;
source_positiv=is_source_positiv(ABL_OPER(cell->ABL));
dest_positiv=is_dest_positiv(ABL_OPER(cell->ABL),ABL_ARITY(cell->ABL));
/*operator no matches*/
if (source_positiv==-1 || dest_positiv==-1) return all_note;
/*search if there is already a couple of this arity*/
for (note=all_note; note; note=note->NEXT) {
if (note->ARITY==ABL_ARITY(cell->ABL)) break;
}
/*eval delay*/
for (portchain=ABL_CDR(cell->ABL); portchain; portchain=portchain->NEXT) {
port=(port_list*) ABL_ATOM_VALUE(ABL_CAR(portchain));
delay=port->T ;
delay+=source_positiv?entry->DELAY:entry->NEG_DELAY;
/*sortance=1*/
delay+= port->C * (source_positiv?entry->R:entry->NEG_R);
if (delay>latest) {latest=delay; R=port->R;}
/*if worse than last record, skip it*/
if (dest_positiv) {
if (latest>=last_input->DELAY) return all_note;
}
else if (latest>=last_input->NEG_DELAY) return all_note;
if (note) {
/*if worse than last record, skip it*/
if (dest_positiv) {
if (latest>=note->DELAY) return all_note;
}
else if (latest>=note->NEG_DELAY) return all_note;
}
entry=entry->NEXT;
}
/*eval cost -> it is the place in the rest of the entry*/
for (cost=1; entry; entry=entry->NEXT) {
delay=dest_positiv?entry->DELAY:entry->NEG_DELAY;
if (latest<=delay) break;
cost++;
}
/*if after all entry algorithm don't work*/
if (!entry) return all_note;
/*create a new couple if doesn't exist*/
if (!note) {
note=newnote();
note->NEXT=all_note;
all_note=note;
note->ARITY=ABL_ARITY(cell->ABL);
}
/*take new solution*/
if (dest_positiv) {
note->DELAY=latest;
note->R=R;
note->COST=cost;
note->CELL=cell;
}
else {
note->NEG_DELAY=latest;
note->NEG_R=R;
note->NEG_COST=cost;
note->NEG_CELL=cell;
}
return all_note;
}
/***************************************************************************/
/* unflatten to improve speed */
/* try to reduce the number of entries without changing the latest entry */
/*a cell inserted must produce an output delay shortest than latest entry */
/* return the new list of entry after insertion */
/* if no cell can satisfy condition result the entry list unchanged */
/***************************************************************************/
extern input_list* unflatten_delay(input_list *entry, int entry_number, input_list* last_entry)
{
input_list *pred = NULL, *input, *new_input;
chain_list* abl;
cell_list* cell;
note_list* note, *all_note=NULL, *best_note;
int cell_source_positiv, neg_cell_source_positiv; /*flag*/
if (!entry) {
fprintf(stderr,"unflatten_delay: no input\n");
exit(1);
}
/*test all the simple logic library*/
for (cell=getcell_oper_lib(); cell; cell=cell->NEXT) {
all_note=eval_note(all_note, cell, entry, entry_number, last_entry);
}
/*no result pattern, impossible to map, signal it to caller function*/
if (!all_note) return entry;
/*take the earliest or the biggest on average results*/
best_note=all_note;
best_note->AVERAGE_COST=(best_note->COST+best_note->NEG_COST)/2;
for (note=all_note->NEXT; note; note=note->NEXT) {
note->AVERAGE_COST=(note->COST+note->NEG_COST)/2;
if (note->AVERAGE_COST<best_note->AVERAGE_COST) best_note=note;
else if (note->AVERAGE_COST==best_note->AVERAGE_COST
&& note->ARITY>best_note->ARITY) best_note=note;
else if (note->AVERAGE_COST==best_note->AVERAGE_COST
&& note->ARITY==best_note->ARITY
&& note->DELAY+note->NEG_DELAY<best_note->DELAY+best_note->NEG_DELAY)
best_note=note;
}
/*only one cell respect condtions, we need its dual cell*/
if (!best_note->CELL || !best_note->NEG_CELL) {
/*algorithm don't know how to unflat*/
freenote(all_note);
return entry;
}
/*build new input*/
new_input=newinput();
new_input->DELAY=best_note->DELAY;
new_input->NEG_DELAY=best_note->NEG_DELAY;
new_input->R=best_note->R;
new_input->NEG_R=best_note->NEG_R;
new_input->ABL=createabloper(ABL_OPER(best_note->CELL->ABL));
new_input->NEG_ABL=createabloper(ABL_OPER(best_note->NEG_CELL->ABL));
cell_source_positiv=is_source_positiv(ABL_OPER(best_note->CELL->ABL));
neg_cell_source_positiv=is_source_positiv(
ABL_OPER(best_note->NEG_CELL->ABL));
/*put operands*/
for (input=entry; input; input=input->NEXT) {
if (best_note->ARITY==0) break;
best_note->ARITY--;
/*positiv*/
if (cell_source_positiv) {
abl=input->ABL;
input->ABL=NULL; /* protect from freeinput() */
}
else {
abl=input->NEG_ABL;
input->NEG_ABL=NULL; /* protect from freeinput() */
}
ABL_CDR(new_input->ABL)=addchain(ABL_CDR(new_input->ABL),abl);
/*opposite*/
if (neg_cell_source_positiv) {
if (input->ABL) abl=input->ABL;
else abl=dupablexpr(abl); /*already used above*/
input->ABL=NULL; /* protect from freeinput() */
}
else {
if (input->NEG_ABL) abl=input->NEG_ABL;
else abl=dupablexpr(abl); /*already used above*/
input->NEG_ABL=NULL; /* protect from freeinput() */
}
ABL_CDR(new_input->NEG_ABL)=addchain(ABL_CDR(new_input->NEG_ABL),abl);
pred=input;
}
pred->NEXT=NULL;
freeinput(entry);
freenote(all_note);
return sort_input(input,new_input); /*return a sort list*/
}

View File

@ -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 : BooG - unflatten with optimized delay
* Date : 2000
* Author : Francois Donnet
*/
#ifndef UNFLATTEN_DELAY_H
#define UNFLATTEN_DELAY_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/***************************************************************************/
/* try to reduce the number of entries without changing the latest entry */
/*a cell inserted must produce an output delay shortest than latest entry */
/* return the new list of inputs after insertion */
/* if no cell can satisfy condition result the entry list unchanged */
/***************************************************************************/
extern input_list* unflatten_delay __P ((input_list *entry, int entry_number, input_list* last_entry));
#endif

View File

@ -0,0 +1,222 @@
/*
* 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 : BooG - unflatten an operator
* Date : 2000
* Author : Francois Donnet
*/
#include <mut.h>
#include <mlo.h>
#include <abl.h>
#include <abe.h>
#include "bog_lax_param.h"
#include "bog_normalize_ARITY.h"
#include "bog_normalize_message.h"
#include "bog_lib_utils.h"
#include "bog_lib_complete.h"
#include "bog_signal_utils.h"
#include "bog_map_pattern.h"
#include "bog_unflatten_utils.h"
#include "bog_unflatten_delay.h"
#include "bog_unflatten_area.h"
#include "bog_unflatten_oper.h"
static int OPER; /*oper we have to reduce*/
static int SIZE; /*number of inputs of this oper*/
/**************************************************************************/
/* return -1 if oper not match with OPER */
/* 0 if oper gives inverted destination */
/* 1 if oper gives positiv destination */
/**************************************************************************/
extern int is_dest_positiv(int oper, int arity)
{
/*WARNING it's not so easy to understand...*/
/*NAND, NOR become and AND, OR if they aren't last*/
switch (OPER) {
case ABL_NAND:
if (arity==SIZE) /*if not last operator we need positive operator*/
switch (oper) {
case ABL_OR: case ABL_NAND: return 1;
case ABL_AND: case ABL_NOR: return 0;
default: return -1;
}
case ABL_AND: /*ABL_NAND is like ABL_AND if not last*/
switch (oper) {
case ABL_AND: case ABL_NOR: return 1;
case ABL_OR: case ABL_NAND: return 0;
default: return -1;
}
case ABL_NOR:
if (arity==SIZE) /*if not last operator we need positive operator*/
switch (oper) {
case ABL_AND: case ABL_NOR: return 1;
case ABL_OR: case ABL_NAND: return 0;
default: return -1;
}
case ABL_OR: /*ABL_NOR is like ABL_OR if not last*/
switch (oper) {
case ABL_OR: case ABL_NAND: return 1;
case ABL_AND: case ABL_NOR: return 0;
default: return -1;
}
case ABL_NXOR:
if (arity==SIZE) /*if not last operator we need positive operator*/
switch (oper) {
case ABL_XOR: return 0;
case ABL_NXOR: return 1;
default: return -1;
}
case ABL_XOR:
switch (oper) {
case ABL_XOR: return 1;
case ABL_NXOR: return 0;
default: return -1;
}
case ABL_STABLE: case ABL_NOT: return -1;
default:
fprintf(stderr,"is_dest_positiv: %d operator unknown\n",OPER);
exit(1);
}
}
/**************************************************************************/
/* return -1 if oper not match with OPER */
/* 0 if oper needs inverted source */
/* 1 if oper needs positiv source */
/**************************************************************************/
extern int is_source_positiv(int oper)
{
switch (OPER) {
case ABL_AND: case ABL_NAND:
switch (oper) {
case ABL_AND: case ABL_NAND: return 1;
case ABL_OR: case ABL_NOR: return 0;
default: return -1;
}
case ABL_OR: case ABL_NOR:
switch (oper) {
case ABL_OR: case ABL_NOR: return 1;
case ABL_AND: case ABL_NAND: return 0;
default: return -1;
}
case ABL_XOR:
switch (oper) {
case ABL_XOR: return 1;
case ABL_NXOR: return 1;
default: return -1;
}
case ABL_NXOR:
switch (oper) {
case ABL_XOR: return 1;
case ABL_NXOR: return 1;
default: return -1;
}
case ABL_STABLE: case ABL_NOT: return -1;
default:
fprintf(stderr,"is_source_positiv: %d operator unknown\n",OPER);
exit(1);
}
}
/***************************************************************************/
/* return the unflat output and its inverted value */
/***************************************************************************/
extern input_list* unflatten_oper(int oper, input_list* entry)
{
input_list* pred, *last = NULL, *input;
if (!entry) {
fprintf(stderr,"unflatten_oper: NULL pointer\n");
exit(1);
}
/*no problem of arity for not*/
if (oper==ABL_NOT) {
chain_list* abl;
float delay,R;
R=entry->R;
delay=entry->DELAY;
abl=entry->ABL;
entry->R=entry->NEG_R;
entry->DELAY=entry->NEG_DELAY;
entry->ABL=entry->NEG_ABL;
entry->NEG_R=R;
entry->NEG_DELAY=delay;
entry->NEG_ABL=abl;
return entry;
}
/*solve problem of arity*/
OPER=oper;
is_source_positiv(oper);/*verify validity of operator*/
/*we want only one input*/
while (entry->NEXT) {
/*number of entry*/
SIZE=0;
for (input=entry; input; input=input->NEXT) {
SIZE++;
last=input;
}
pred=entry;
/*optimize in area or in delay*/
if (getoptimlax()>OPTIM_DELAY0) {
entry=unflatten_delay(entry, SIZE, last);
if (!entry) {
fprintf(stderr,"unflatten_oper: unflatten_delay() return NULL\n");
exit(1);
}
if (entry!=pred) continue;
/*if no result, try another algorithm*/
}
/*optimize in area*/
entry=unflatten_area(entry, SIZE);
if (!entry) {
fprintf(stderr,"unflatten_oper: unflatten_area() return NULL\n");
exit(1);
}
if (entry==pred) {
fprintf(stderr,
"unflatten_oper: Impossible to map oper %d with arity %d\n",
OPER, SIZE);
exit(1);
}
}
return entry;
}

View File

@ -0,0 +1,64 @@
/*
* 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 : BooG - unflatten an operator
* Date : 2000
* Author : Francois Donnet
*/
#ifndef UNFLATTEN_OPER_H
#define UNFLATTEN_OPER_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/***************************************************************************/
/* return the unflat output and its inverted value */
/***************************************************************************/
extern input_list* unflatten_oper __P ((int oper, input_list* inputs));
/**************************************************************************/
/* return -1 if oper not match with OPER */
/* 0 if oper needs inverted source */
/* 1 if oper needs positiv source */
/**************************************************************************/
extern int is_source_positiv __P ((int oper));
/**************************************************************************/
/* return -1 if oper not match with OPER */
/* 0 if oper gives inverted destination */
/* 1 if oper gives positiv destination */
/**************************************************************************/
extern int is_dest_positiv __P ((int oper, int arity));
#endif

View File

@ -0,0 +1,201 @@
/*
* 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 : BooG - inputs treatment
* Date : 2000
* Author : Francois Donnet
*/
#ifdef AUTO_HAS_VALUES_H
# include <values.h>
#else
# include <float.h>
# ifndef MAXFLOAT
# define MAXFLOAT FLT_MAX
# endif
#endif
#include <mut.h>
#include <abl.h>
#include <abe.h>
#include "bog_lax_param.h"
#include "bog_lib_utils.h"
#include "bog_unflatten_utils.h"
#define BLOCK 512
/*heaps of structure*/
static input_list* HEAD;
static note_list* HEAD_NOTE;
/***************************************************************************/
/* give a new element from the heap */
/***************************************************************************/
extern input_list* newinput()
{
input_list* new;
int i;
if (!HEAD) {
HEAD=mbkalloc(BLOCK*sizeof(input_list));
new=HEAD;
for (i = 1; i < BLOCK; i++) {
new->NEXT = new + 1;
new++;
}
new->NEXT = NULL;
}
new=HEAD;
HEAD=HEAD->NEXT;
new->NEXT=NULL;
new->ABL=NULL;
new->NEG_ABL=NULL;
new->R=DEFAULT_CAPACITANCE;
new->NEG_R=DEFAULT_CAPACITANCE;
new->DELAY=MAXFLOAT; /*very important value*/
new->NEG_DELAY=MAXFLOAT; /*very important value*/
return new;
}
/***************************************************************************/
/* free recursively a list of inputs and also their abl */
/***************************************************************************/
extern void freeinput(input_list* head)
{
if (!head) return;
freeinput(head->NEXT);
if (head->ABL) freeablexpr(head->ABL);
if (head->NEG_ABL) freeablexpr(head->NEG_ABL);
/*put back to the heap*/
head->NEXT=HEAD;
HEAD=head;
}
/***************************************************************************/
/* create a new structure and copy all the fields of input */
/***************************************************************************/
extern input_list* dupinput(input_list* input)
{
input_list* new;
new=newinput();
new->NEXT=input->NEXT;
new->ABL=input->ABL;
new->NEG_ABL=input->NEG_ABL;
new->DELAY=input->DELAY;
new->NEG_DELAY=input->NEG_DELAY;
return new;
}
/***************************************************************************/
/* insert new in the list of inputs */
/* sorted by the average of delay and its inverted value delay */
/***************************************************************************/
extern input_list* sort_input(input_list* inputs, input_list* new_input)
{
float average;
input_list* sort, *pred;
if (!new_input) {
fprintf(stderr,"sort_input: no new input to insert\n");
exit(1);
}
average=(new_input->DELAY+new_input->NEG_DELAY)/2;
/*find place of new input*/
pred=NULL;
for (sort=inputs; sort; sort=sort->NEXT) {
if (average<=(sort->DELAY+sort->NEG_DELAY)/2) break;
pred=sort;
}
new_input->NEXT=sort;
if (pred) {
pred->NEXT=new_input;
return inputs;
}
else return new_input;
}
/***************************************************************************/
/* give a new element from the heap */
/***************************************************************************/
extern note_list* newnote()
{
note_list* new;
int i;
if (!HEAD_NOTE) {
HEAD_NOTE=mbkalloc(BLOCK*sizeof(note_list));
new=HEAD_NOTE;
for (i = 1; i < BLOCK; i++) {
new->NEXT = new + 1;
new++;
}
new->NEXT = NULL;
}
new=HEAD_NOTE;
HEAD_NOTE=HEAD_NOTE->NEXT;
new->NEXT=NULL;
new->CELL=NULL;
new->NEG_CELL=NULL;
new->COST=MAXFLOAT;
new->NEG_COST=MAXFLOAT;
new->AVERAGE_COST=MAXFLOAT;
new->DELAY=MAXFLOAT; /*very important value, do not change!*/
new->NEG_DELAY=MAXFLOAT; /*do not change*/
new->R=DEFAULT_CAPACITANCE;
new->NEG_R=DEFAULT_CAPACITANCE;
new->ARITY=0;
return new;
}
/***************************************************************************/
/* free recursively a list of notes */
/***************************************************************************/
extern void freenote(note_list* head)
{
if (!head) return;
freenote(head->NEXT);
/*put back to the heap*/
head->NEXT=HEAD_NOTE;
HEAD_NOTE=head;
}

View File

@ -0,0 +1,105 @@
/*
* 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 : BooG - inputs treatment
* Date : 2000
* Author : Francois Donnet
*/
#ifndef UNFLATTEN_UTILS_H
#define UNFLATTEN_UTILS_H
#ifndef __P
# ifdef __STDC__ || __GNUC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
/*to represent the duality of each input*/
typedef struct input {
struct input *NEXT;
chain_list *ABL;
chain_list *NEG_ABL;
float DELAY;
float NEG_DELAY;
float R;
float NEG_R;
} input_list;
/*for evaluation of a dual solution which gives an output and its opposite*/
typedef struct note {
struct note* NEXT;
cell_list* CELL;
cell_list* NEG_CELL;
float COST;
float NEG_COST;
float AVERAGE_COST;
float DELAY;
float NEG_DELAY;
float R;
float NEG_R;
int ARITY;
} note_list;
/***************************************************************************/
/* give a new element from the heap */
/***************************************************************************/
extern input_list* newinput __P (());
/***************************************************************************/
/* free recursively a list of inputs and also their abl */
/***************************************************************************/
extern void freeinput __P ((input_list* head));
/***************************************************************************/
/* create a new structure and copy all the fields of input */
/***************************************************************************/
extern input_list* dupinput __P ((input_list* input));
/***************************************************************************/
/* insert new in the list of inputs */
/* sorted by the average of delay and its inverted value delay */
/***************************************************************************/
extern input_list* sort_input __P ((input_list* new_input, input_list* inputs));
/***************************************************************************/
/* give a new element from the heap */
/***************************************************************************/
extern note_list* newnote __P (());
/***************************************************************************/
/* free recursively a list of notes */
/***************************************************************************/
extern void freenote __P ((note_list* head));
#endif

View File

@ -0,0 +1,387 @@
/*
* 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 : 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 "bog_lib_utils.h"
#include "bog_signal_utils.h"
#include "bog_signal_nameindex.h"
#include "bog_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(float delay, float 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, float delay)
{
char memo_char;
long index;
/*forbid vector*/
index=vectorindex(name);
if (index>=0) {
memo_char=SEPAR;
SEPAR='_';
name=nameindex(vectorradical(name),index);
SEPAR=memo_char;
}
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, float delay, char losig_type)
{
char memo_char;
long index;
/*forbid vector for loins*/
index=vectorindex(source);
if (index>=0) {
memo_char=SEPAR;
SEPAR='_';
source=nameindex(vectorradical(source),index);
SEPAR=memo_char;
}
/*forbid vector for loins*/
index=vectorindex(dest);
if (index>=0) {
memo_char=SEPAR;
SEPAR='_';
dest=nameindex(vectorradical(dest),index);
SEPAR=memo_char;
}
/*forbid vector for internal signal*/
index=vectorindex(signame);
if (losig_type==INTERNAL && index>=0) {
memo_char=SEPAR;
SEPAR='_';
signame=nameindex(vectorradical(signame),index);
SEPAR=memo_char;
}
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, float delay, char losig_type)
{
char memo_char;
long index;
/*forbid vector for internal signal*/
index=vectorindex(name);
if (losig_type==INTERNAL && index>=0) {
memo_char=SEPAR;
SEPAR='_';
name=nameindex(vectorradical(name),index);
SEPAR=memo_char;
}
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;
float delay=0, delay_out=0;
char mes[1024];
char* signame;
locon_list* locon;
losig_list* losig;
float 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/((float)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, losig->TYPE);
}
/*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;
signame=losig->NAMECHAIN->DATA;
delay=getdelay(loins_name(loins->INSNAME));
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;
/*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->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, INTERNAL);
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, losig->TYPE);
}
}
freechain(loinschain);
}

View File

@ -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 : 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