/* * 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 : mailto:alliance-users@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 #include #include #include #include #include #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 (latestPORT 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 (latestPORT 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 (latestBIABL; biabl_aux; biabl_aux=biabl_aux->NEXT) biabl=biabl->NEXT; /*look the other blocks*/ if (biabl) { delay=eval_bus(name,biabl); if (latestNEXT) { 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 (latestNEXT) { 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 (latestBIABL; biabl_aux; biabl_aux=biabl_aux->NEXT) biabl=biabl->NEXT; /*look the other blocks*/ if (biabl) { delay=eval_reg(name,biabl); if (latestPORT 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 (latestBIABL; biabl_aux; biabl_aux=biabl_aux->NEXT) biabl=biabl->NEXT; /*look the other blocks*/ if (biabl) { delay=eval_value_reg(biabl); if (latestNEXT) { 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 (latestNEXT) { 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 (latestBIABL; biabl_aux; biabl_aux=biabl_aux->NEXT) biabl=biabl->NEXT; /*look the other blocks*/ if (biabl) { delay=eval_clock_reg(biabl); if (latestPORT 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 (latestBIABL; biabl_aux; biabl_aux=biabl_aux->NEXT) biabl=biabl->NEXT; /*look the other blocks*/ if (biabl) { delay=loc_eval_bus(biabl,C); if (latest