diff --git a/alliance/src/sea/Makefile.am b/alliance/src/sea/Makefile.am new file mode 100644 index 00000000..9dd5545d --- /dev/null +++ b/alliance/src/sea/Makefile.am @@ -0,0 +1,3 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = src diff --git a/alliance/src/sea/configure.in b/alliance/src/sea/configure.in new file mode 100644 index 00000000..eabc073b --- /dev/null +++ b/alliance/src/sea/configure.in @@ -0,0 +1,36 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(src/DEF2a.c) + +SEA_MAJOR_VERSION=1 +SEA_MINOR_VERSION=0 +SEA_VERSION=$SEA_MAJOR_VERSION.$SEA_MINOR_VERSION + +AC_SUBST(SEA_MAJOR_VERSION) +AC_SUBST(SEA_MINOR_VERSION) +AC_SUBST(SEA_VERSION) + +# For automake. +VERSION=$SEA_VERSION +PACKAGE=sea + +dnl Initialize automake stuff +AM_INIT_AUTOMAKE($PACKAGE, $VERSION) + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_RANLIB +AM_PROG_LEX +AC_PROG_YACC +AC_PROG_MAKE_SET + +AC_CHECK_LIB(m, pow) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST + +AM_ALLIANCE + +AC_OUTPUT([ +Makefile +src/Makefile +]) diff --git a/alliance/src/sea/src/DEF2a.c b/alliance/src/sea/src/DEF2a.c new file mode 100644 index 00000000..1ed8d77f --- /dev/null +++ b/alliance/src/sea/src/DEF2a.c @@ -0,0 +1,241 @@ +/* + * $Id: DEF2a.c,v 1.1 2002/04/25 16:16:19 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Mael Nagat | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./DEF2a.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" +# include "DEF_grammar.h" + + +/* ------------------------------------------------------------------ + * Local constants. + */ + +# define F_PHFIG 0x00000001 +# define F_LOFIG 0x00000002 +# define F_SPLIT_POWER 0x00000004 +# define F_SHRINK 0x00000008 +# define F_NO_IOS 0x00000010 +# define F_NO_INTERF 0x00000020 +# define F_MERGE_TERM 0x00000040 +# define M_OUTPUT (F_PHFIG | F_LOFIG) + + +/* ------------------------------------------------------------------ + * Local variables. + */ + + static long LV_VL; /* Verbose level. */ + static long LV_flags; + + +/* ---------------------------------------------------------------------- + * Internal functions declarations. + */ + + static void printHelp __FP((void)); + static void getlophfig __FP((lofig_list **appLoFig, + phfig_list **appPhFig, + char *aDefName, + char *aNetlayName, + char aMode, + long aVL, + long aFlags)); + + +/* + * /--------------------------------------------------------------------\ + * | Functions Definitions | + * \--------------------------------------------------------------------/ + */ + +/* ---------------------------------------------------------------------- + * Function : "printHelp()". + */ + +static void printHelp() +{ + printf (" o Usage := \"DEF2a <-l|-p|-l -p>"); + printf ( " [-v] [-V] [-h] [-s] [-b] [-i] [-r]\n"); + printf (" []\"\n\n"); + printf (" o Options :\n"); + printf (" [-v] := Be verbose.\n"); + printf (" [-V] := Be very verbose.\n"); + printf (" [-h] := Print this message.\n"); + printf (" [-l] := Drive the logical figure.\n"); + printf (" [-p] := Drive the physical figure.\n"); + printf (" [-b] := Suppress AB terminals.\n"); + printf (" [-s] := Split the power nets.\n"); + printf (" [-S] := Shrink the abutment box.\n"); + printf (" [-i] := Do not build physical interface.\n"); + printf (" [-r] := Merge power terminals for ring.\n"); + printf (" := Name of the input DEF file (mandatory).\n"); + printf (" := Name of the output netlist and/or layout.\n"); + printf ("\n" ); +} + + +/* ---------------------------------------------------------------------- + * Function : "getlophfig()". + */ + +static void getlophfig (appLoFig, + appPhFig, + aDefName, + aNetlayName, + aMode, + aVL, + aFlags) + lofig_list **appLoFig; + phfig_list **appPhFig; + char *aDefName; + char *aNetlayName; + char aMode; + long aVL; + long aFlags; +{ + (*appLoFig) = addlofig (aNetlayName); + (*appPhFig) = addphfig (aNetlayName); + + defloadlophfig ((*appLoFig), (*appPhFig), aDefName, aMode, aVL, aFlags); +} + + + +/* ---------------------------------------------------------------------- + * Function : "main()". + */ + +extern int main (argc, argv) + int argc; + char *argv[]; +{ + struct phfig *pPhFig; + struct lofig *pLoFig; + char *defName; + char *netlayName; + long defFlags; + int argC, i; + + + /* Read MBK environment. */ + mbkenv(); + + argC = argc; + + /* Default options. */ + defFlags = 0L; + LV_flags = 0L; + + + /* Initialise the "Ut" module. */ + util_init (C_VerboseLevel0, F_DUMPCORE, "DEF2a"); + + + /* Read the options. */ + for (i = 1; i < argc; i++) { + if (!strcmp (argv[i], "-h")) { printHelp (); exit (0); } + if (!strcmp (argv[i], "-v")) { LV_VL = C_VerboseLevel1; continue; } + if (!strcmp (argv[i], "-V")) { LV_VL = C_VerboseLevel2; continue; } + if (!strcmp (argv[i], "-p")) { defFlags |= F_PHFIG; continue; } + if (!strcmp (argv[i], "-l")) { defFlags |= F_LOFIG; continue; } + if (!strcmp (argv[i], "-s")) { defFlags |= F_SPLIT_POWER; continue; } + if (!strcmp (argv[i], "-S")) { defFlags |= F_SHRINK; + LV_flags |= F_DEF_SHRINK;continue; } + if (!strcmp (argv[i], "-b")) { defFlags |= F_NO_IOS; + LV_flags |= F_DEF_NO_IOS; continue; } + if (!strcmp (argv[i], "-i")) { defFlags |= F_NO_INTERF; + LV_flags |= F_DEF_NO_INTERF; continue; } + if (!strcmp (argv[i], "-r")) { defFlags |= F_MERGE_TERM; + LV_flags |= F_DEF_MERGE_TERM; continue; } + + if ((argC - i) > 2) { + eprinth (NULL); + eprintf ("Unknown argument \"%s\"\n\n", argv[argC - 1]); + printHelp (); + exit (1); + } + else + break; + } + + + if ((argC - i) < 1) { + eprinth (NULL); + eprintf ("Missing DEF file name .\n\n"); + printHelp (); + exit (1); + } else { + defName = namealloc (argv[i]); + + if ((argC - i) >= 2) + netlayName = namealloc (argv[i + 1]); + else + netlayName = defName; + } + + + if (!(defFlags & M_OUTPUT)) { + eprinth ("DEF2a"); + eprints ("Neither <-p> nor <-l> is present.\n\n"); + printHelp (); + + exit (1); + } + + + setVL (LV_VL); + + if (LV_VL > 0) { + alliancebanner( + "DEF2a", "V.RR", "Alliance to DEF converter", + "2000", ALLIANCE_VERSION); + } + + printMBKEnv (); + if (defFlags & F_PHFIG) mprintf1 (" o Extract physical datas.\n"); + if (defFlags & F_LOFIG) mprintf1 (" o Extract logical datas.\n"); + if (defFlags & F_SPLIT_POWER) { + mprintf1 (" o Split the power nets.\n"); + LV_flags |= F_DEF_SPLIT_POWER; + } + + + mprintf1 (" o Parsing \"%s\".\n", defName); + getlophfig (&pLoFig, &pPhFig, defName, netlayName, 'A', LV_VL, LV_flags); + + if ((defFlags & F_SHRINK) && (defFlags & F_PHFIG)) { + mprintf1 (" o Shrinking abutment-box.\n"); + shrinkFloorplan (pPhFig); + } + + mprintf1 (" o Building obstacles.\n"); + rtu (pPhFig); + + if (defFlags & F_PHFIG) { + mprintf1 (" o Driving \"%s\" (physical).\n", netlayName); + savephfig (pPhFig); + } + + if (defFlags & F_LOFIG) { + mprintf1 (" o Driving \"%s\" (logical).\n", netlayName); + savelofig (pLoFig); + } + + + exit(0); +} diff --git a/alliance/src/sea/src/DEF_actions.c b/alliance/src/sea/src/DEF_actions.c new file mode 100644 index 00000000..cd9bd0f0 --- /dev/null +++ b/alliance/src/sea/src/DEF_actions.c @@ -0,0 +1,1794 @@ + +/* + * $Id: DEF_actions.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./DEF_actions.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "debugoff.h" +# include "util_Defs.h" +# include "DEF_actions.h" +# include "DEF_grammar.h" + + + /* Flex substitutions. */ +# define yylex DEF_grammarlex +# define yyin DEF_grammarin +# define yylineno DEF_grammarlineno + + /* Bison substitutions. */ +# define yyparse DEF_grammarparse +# define yydebug DEF_grammardebug + + +# define SIZE_TPT 1024 +# define SIZE_TDATALAYER 16 +# define SIZE_TDATACUT 16 +# define SIZE_TDATAVIA 128 +# define SIZE_TPIN 512 +# define F_DATA_SET 0x00000001 +# define F_PIN_STATE 0x00000001 +# define F_PIN_LAYER 0x00000002 +# define F_PIN_DIRECTION 0x00000004 +# define M_PIN_ISPLACED (F_PIN_STATE | F_PIN_LAYER) +# define F_VIA_CUT 0x00000001 +# define F_VIA_PATTERN 0x00000002 +# define F_SEG_INITIAL 0x00000001 +# define F_SEG_SPECIAL 0x00000002 +# define F_SEG_PIN 0x00000004 +# define F_SEG_BLOCKAGE 0x00000008 + + +/* ------------------------------------------------------------------ + * Internal types. + */ + + + typedef struct dataLayer_s { + char layer; /* MBK layer. */ + char clayer; /* MBK terminal layer. */ + char flags; /* Tell if this entry is set. */ + char *name; /* "nameallocatted" name of the layer. */ + long width; /* layer minimal width. */ + } dataLayer_t; + + + typedef struct dataCut_s { + char VIA; /* MBK VIA. */ + char flags; /* Tell if this entry is set . */ + char *name; /* "namellocatted" name of the cut layer. */ + } dataCut_t; + + + typedef struct dataVIA_s { + char VIA; /* MBK VIA or TURN_VIA. */ + char flags; /* Tell if this entry is set . */ + char *name; /* "namellocatted" name of the via . */ + long width; /* VIA width. */ + long height; /* VIA height. */ + } dataVIA_t; + + + typedef struct pin_s { + char *pinName; + char *netName; + } pin_t; + + +/* ------------------------------------------------------------------ + * Local variables (prefix 'LV_'). + */ + + static char *LV_IN_PH = "def"; + static struct lofig *LV_pLoFig; + static struct phfig *LV_pPhFig; + static struct phins *LV_pPhIns; + static char *LV_name; + static char LV_mode; + static char LV_defFlags; + static char *LV_blockageName; + static struct dataLayer_s tDataLayer[SIZE_TDATALAYER]; + static struct dataCut_s tDataCut[SIZE_TDATACUT]; + static struct dataVIA_s tDataVIA[SIZE_TDATAVIA]; + static long LV_mVIA = 0L; + static long LV_mPin; + static struct pin_s *LV_tPin; + static struct authtable *LV_htPin; + static char *LV_modelName; + static long LV_flags; + static long LV_orient; + static char LV_layer; + static char LV_VIA; + static long LV_width; + static long LV_height; + static long LV_lastX; + static long LV_lastY; + static struct pt *LV_ptCurrent; + static struct pt *LV_pt1; + static struct pt *LV_pt2; + static long LV_numPins; + static long LV_numObjects; + static long LV_numObjectsRead; + static long LV_direction; + static long LV_mSig; + static struct losig *LV_pLoSig; + static struct tLoseg_s *LV_ptLoseg; + + +/* ------------------------------------------------------------------ + * Internal functions. + */ + +# define IS_X_PT(pt) ((pt)->x != HUGE_VAL) +# define IS_Y_PT(pt) ((pt)->y != HUGE_VAL) +# define IS_XY_PT(pt) (IS_X_PT(pt) && IS_Y_PT(pt)) + + + static void initDataTables __FP((void)); + static void setDataLayer __FP(( int aN, + char *aName, + char aLayer, + char aCLayer, + long aWidth)); + static void setDataCut __FP(( int aN, + char *aName, + char aCut)); + static void addDataVIA __FP((char *aName, + char aCut, + long width, + long height)); + static dataVIA_t *DEF2MBK_dataVIA __FP((char *aName)); + static long DEF_isLayer __FP((char *aName)); + static char DEF2MBK_layer __FP((char *aName)); + static long DEF2MBK_layerWidth __FP((char *aName)); + static long MBK_layerWidth __FP((char aLayer)); + static char DEF2MBK_dataCut __FP((char *aName)); + static void orderCoord __FP((long *aX1, long *aX2)); + static void DEF_pinxyflat __FP((long *apX_flat, long *apY_flat, + long aX , long aY , + long aX_ins , long aY_ins , + char aT)); + + +/* ------------------------------------------------------------------ + * Functions from Bison/flex. + */ + + extern FILE *yyin; + extern long yylineno; + extern int yydebug; + extern int yyparse __FP((void)); + + + +/* + * /----------------------------------------------------------------\ + * | Functions Definitions | + * \----------------------------------------------------------------/ + */ + +/* ------------------------------------------------------------------ + * Function : "def_design_name()". + */ + +extern void def_design_name(name) + char *name; +{ + if (strcmp (name, LV_pPhFig->NAME)) { + warnMBK ("DEFloadphlofig"); + wprintf ("\n The design name \"%s\" doesn't match with the", name); + wprintf (" file name \"%s\" (.%s).\n", LV_pPhFig->NAME, LV_IN_PH); + } +} + + +/* ------------------------------------------------------------------ + * Function : "def_tech_name()". + */ + +extern void def_tech_name(char *name) +{ +} + + +/* ------------------------------------------------------------------ + * Function : "def_end_design()". + */ + +extern void def_end_design(void) +{ +} + + +/* ------------------------------------------------------------------ + * Function : "def_units()". + */ + +extern void def_units(number) + double number; +{ + DEF_UNITS_MICRONS = (long)number; +} + + +/* ------------------------------------------------------------------ + * Function : "def_die_area()". + */ + +extern void def_die_area(ab1, ab2) + struct pt *ab1, *ab2; +{ + if ( !IS_XY_PT (ab1) || !IS_XY_PT (ab2) ) { + errMBK ("defloadlophfig"); + eprintf ("Invalid coordinate '*' in DIEAREA at line %ld.\n", + yylineno); + EXIT (1); + } + + if (LV_pPhFig) + defab(LV_pPhFig, DEF2MBK_length ((long)(ab1->x)), + DEF2MBK_length ((long)(ab1->y)), + DEF2MBK_length ((long)(ab2->x)), + DEF2MBK_length ((long)(ab2->y))); + + def_free_pt (ab1); + def_free_pt (ab2); +} + + +/* ------------------------------------------------------------------ + * Function : "def_row_rule()". + */ + +extern void def_row_rule(row_name, row_type, x, y, orient, + do_number, by_number, step_x, step_y) + char *row_name; + char *row_type; + double x, y, orient, do_number, by_number, step_x, step_y; +{ + if (LV_pPhFig) { + DEF2MBK_row(LV_pPhFig, + row_name, + row_type, + (long)orient, + (long)do_number, + (long)by_number, + (long)step_x, + (long)step_y, + DEF2MBK_length ((long)x), + DEF2MBK_length ((long)y)); + } + + + free (row_name); + free (row_type); +} + + +/* ------------------------------------------------------------------ + * Function : "def_track_rule()". + */ + +extern void def_track_rule(axis_name, start, do_number, step, layer_list) + char *axis_name; + double start; + double do_number; + double step; + char *layer_list; +{ + long xREF, yREF; + + + + if (LV_pPhFig) { + switch (axis_name[0]) { + case 'Y': + case 'y': + xREF = LV_pPhFig->XAB1; + yREF = DEF2MBK_length ((long)start); + break; + case 'X': + case 'x': + default: + xREF = DEF2MBK_length ((long)start); + yREF = LV_pPhFig->YAB1; + } + + DEF2MBK_track(LV_pPhFig, + axis_name, + (long)start, + (long)do_number, + (long)step, + layer_list, + xREF, + yREF); + } + + + free (axis_name); +} + + +/* ------------------------------------------------------------------ + * Function : "def_track_layers()". + */ + +extern char *def_track_layers(layer_name, layer_list) + char *layer_name; + char *layer_list; +{ + char *layerList; + + + layerList = s64printf ("%s.%s", layer_name, layer_list); + + free (layer_name); + + return (layerList); +} + + +/* ------------------------------------------------------------------ + * Function : "def_start_pins()". + */ + + +extern void def_start_pins(number) + double number; +{ + LV_numObjects = (long)number; + LV_numObjectsRead = 0L; + LV_numPins = 0L; + LV_mPin = LV_numObjects; + + LV_tPin = (pin_t*)malloc (sizeof (pin_t) * LV_numObjects); + + /* Half empty HT are faster. */ + LV_htPin = createauthtable (LV_numObjects); +} + + +/* ------------------------------------------------------------------ + * Function : "def_end_pins()". + */ + +extern void def_end_pins(void) +{ + if (LV_numObjects != LV_numObjectsRead) { + warnMBK ("DEFloadlophig"); + wprintf ("Invalid pins number : %d, (%d read)\n", + LV_numObjects, LV_numObjectsRead); + } +} + + +/* ------------------------------------------------------------------ + * Function : "def_pin_start()". + */ + +extern void def_pin_start(char *pin_name, char *net_name) +{ + char *netName; + + + netName = DEF2MBK_name (net_name); + + if ((searchauthelem (LV_htPin, netName)) == NULL) { + addauthelem (LV_htPin, netName, LV_numPins); + + if (LV_numPins >= LV_mPin) { + LV_mPin += SIZE_TPIN; + LV_tPin = (struct pin_s*)realloc ( + LV_tPin, sizeof (struct pin_s) * LV_mPin); + + if (!LV_tPin) { + eprinth ("defloadlophfig"); + eprintf ("\n Not enougth memory to re-allocate \"LV_tPin[]\".\n"); + EXIT (1); + } + } + + LV_tPin[LV_numPins].netName = netName; + LV_tPin[LV_numPins].pinName = DEF2MBK_name (pin_name); + + LV_numPins++; + } + + LV_flags = 0L; + LV_direction = UNKNOWN; + + LV_numObjectsRead++; + + free (pin_name); + free (net_name); +} + + +/* ------------------------------------------------------------------ + * Function : "def_pin_options()". + */ + +extern void def_pin_options() +{ + char *netName; + char orientCon; + long xCon, yCon, widthCon, lengthCon, fakeCon; + long xR1 , yR1 , xR2 , yR2; + long xFR1, yFR1, xFR2, yFR2; + losig_list *pLoSig; + phseg_list *pPhSeg; + phcon_list *pPhCon; + authelem *pElem; + + + netName = LV_tPin[LV_numPins - 1].netName; + + + /* Process the logical terminal. */ + + if (LV_pLoFig) { + /* The logical terminal/signal pair must be created only once. */ + if (!findlocon (LV_pLoFig, netName)) { + pLoSig = addlosig (LV_pLoFig, + LV_mSig++, + addchain (NULL, (void*)netName), + EXTERNAL); + addlocon (LV_pLoFig, netName, pLoSig, LV_direction); + } + } + + + /* Process the physical terminal, if any. */ + + /* Shuts up "gcc -w" ... */ + xR1 = 0; + yR1 = 0; + xR2 = 0; + yR2 = 0; + xCon = 0; + yCon = 0; + + if (LV_flags & F_PIN_LAYER) { + xR1 = DEF2MBK_length ((long)(LV_pt1->x)); + yR1 = DEF2MBK_length ((long)(LV_pt1->y)); + xR2 = DEF2MBK_length ((long)(LV_pt2->x)); + yR2 = DEF2MBK_length ((long)(LV_pt2->y)) - MBKSCALE(1); + + def_free_pt (LV_pt1); + def_free_pt (LV_pt2); + } + + if (LV_flags & F_PIN_STATE) { + xCon = DEF2MBK_length ((long)(LV_ptCurrent->x)); + yCon = DEF2MBK_length ((long)(LV_ptCurrent->y)); + + def_free_pt (LV_ptCurrent); + } + + + if ((LV_pPhFig) && ((LV_flags & M_PIN_ISPLACED) == M_PIN_ISPLACED)) { + pElem = gettlosegitem (LV_ptLoseg, netName); + + /* Transform (flatten) the PIN segment. */ + DEF_pinxyflat (&xFR1, &yFR1, xR1, yR1, xCon, yCon, LV_orient); + DEF_pinxyflat (&xFR2, &yFR2, xR2, yR2, xCon, yCon, LV_orient); + + orderCoord (&xFR1, &xFR2); + orderCoord (&yFR1, &yFR2); + + + fakeCon = FALSE; + pPhSeg = NULL; /* Shut up "gcc -w ..." */ + /* if (!(LV_defFlags & F_DEF_NO_IOS)) { */ + /* Add the physical segment. */ + switch (LV_orient) { + case NOSYM: + case SYM_X: + case SYM_Y: + case SYMXY: + /* Vertical segment. */ + widthCon = xFR2 - xFR1; + lengthCon = yFR2 - yFR1 + MBKSCALE(1); + + if (lengthCon + widthCon < MBK_X_GRID + FLOOR_XY_EXPAND) { + fakeCon = (LV_defFlags & F_DEF_SHRINK) ? TRUE : FALSE; + __DBG( fprintf (stderr, " - Terminal \"%s\" is fake.\n", + netName); ) + } else { + __DBG( fprintf (stderr, " - Terminal \"%s\" is not fake", + netName); + fprintf (stderr, " DY := %ld\n", MBKUNSCALE(lengthCon)); + ) + fakeCon = FALSE; + } + + if (!fakeCon) { + pPhSeg = addphseg (LV_pPhFig, + getCALU (LV_layer), + widthCon, + xFR1 + widthCon / 2, + yFR1, + xFR1 + widthCon / 2, + yFR2, + netName); + } + break; + default: + case ROT_P: + case ROT_M: + case SY_RP: + case SY_RM: + /* horizontal segment. */ + widthCon = yFR2 - yFR1; + lengthCon = xFR2 - xFR1 + MBKSCALE(1); + + if (lengthCon + widthCon < MBK_X_GRID + FLOOR_XY_EXPAND) { + fakeCon = (LV_defFlags & F_DEF_SHRINK) ? TRUE : FALSE; + __DBG( fprintf (stderr, " - Terminal \"%s\" is fake.\n", + netName); ) + } else { + __DBG( fprintf (stderr, " - Terminal \"%s\" is not fake", + netName); + fprintf (stderr, " DX := %ld\n", MBKUNSCALE(lengthCon)); + ) + fakeCon = FALSE; + } + + if (!fakeCon) { + pPhSeg = addphseg (LV_pPhFig, + getCALU (LV_layer), + widthCon, + xFR1, + yFR1 + widthCon / 2, + xFR2, + yFR1 + widthCon / 2, + netName); + } + break; + } /* End of "switch (LV_orient)". */ + + if (!fakeCon) { + LV_ptLoseg->tLoseg[pElem->VALUE] = addloseg ( + LV_ptLoseg->tLoseg[pElem->VALUE], LOSEG_SEGCON, (void*)pPhSeg); + + + /* Add the old-style terminal. */ + switch (LV_orient) { + + case NOSYM: /* DEF : N (North). */ + case SYM_X: /* DEF : FN (Flipped North). */ + orientCon = SOUTH; + xCon = xFR1 + widthCon / 2; + yCon = yFR1; + break; + + case SYM_Y: /* DEF : FS (Flipped South). */ + case SYMXY: /* DEF : S (South). */ + orientCon = NORTH; + xCon = xFR1 + widthCon / 2; + yCon = yFR2; + break; + + case ROT_M: /* DEF : E (East). */ + case SY_RM: /* DEF : FE (Flipped East). */ + orientCon = WEST; + xCon = xFR1; + yCon = yFR1 + widthCon / 2; + break; + + default: + case ROT_P: /* DEF : W (West). */ + case SY_RP: /* DEF : FW (Flipped West). */ + orientCon = EAST; + xCon = xFR2; + yCon = yFR1 + widthCon / 2; + break; + } /* End of "switch (LV_orient)". */ + + pPhCon = addphcon (LV_pPhFig, + orientCon, + netName, + xCon, + yCon, + LV_layer, + widthCon); + + LV_ptLoseg->tLoseg[pElem->VALUE] = addloseg ( + LV_ptLoseg->tLoseg[pElem->VALUE], LOSEG_CON, (void*)pPhCon); + } + } + /* } */ +} + + +/* ------------------------------------------------------------------ + * Function : "def_pin_option_direction()". + */ + +extern void def_pin_option_direction(dir) + double dir; +{ + LV_flags |= F_PIN_DIRECTION; + LV_direction = DEF2MBK_direction (dir); +} + + +/* ------------------------------------------------------------------ + * Function : "def_pin_option_place()". + */ + +extern void def_pin_option_place(ptcon, orient) + struct pt *ptcon; + double orient; +{ + LV_flags |= F_PIN_STATE; + LV_ptCurrent = ptcon; + LV_orient = DEF2MBK_transf (orient); +} + + +/* ------------------------------------------------------------------ + * Function : "def_pin_option_layer()". + */ + +extern void def_pin_option_layer(layer_name, pt1, pt2) + char *layer_name; + struct pt *pt1; + struct pt *pt2; +{ + LV_flags |= F_PIN_LAYER; + LV_layer = getALU (DEF2MBK_layer (namealloc (layer_name))); + + LV_pt1 = pt1; + LV_pt2 = pt2; +} + + +/* ------------------------------------------------------------------ + * Function : "def_start_vias()". + */ + + +extern void def_start_vias(number) + double number; +{ + LV_numObjects = (long)number; + LV_numObjectsRead = 0L; + LV_flags = 0L; + /* Reset the VIA table. */ + LV_mVIA = 0L; +} + + +/* ------------------------------------------------------------------ + * Function : "def_end_vias()". + */ + +extern void def_end_vias(void) +{ + if (LV_numObjects != LV_numObjectsRead) { + warnMBK ("DEFloadlophig"); + wprintf ("Invalid VIAs number : %d, (%d read)\n", + LV_numObjects, LV_numObjectsRead); + } +} + + +/* ------------------------------------------------------------------ + * Function : "def_via_start()". + */ + +extern void def_via_start(via_name) + char *via_name; +{ + LV_modelName = namealloc (via_name); + LV_numObjectsRead++; + + free (via_name); +} + + +/* ------------------------------------------------------------------ + * Function : "def_via_stmt_rect()". + */ + +extern void def_via_stmt_rect(layer_name, pt1, pt2) + char *layer_name; + struct pt *pt1, *pt2; +{ + char *DEF_layer; + + + DEF_layer = namealloc (layer_name); + + if (DEF_isLayer (DEF_layer)) { + LV_layer = DEF2MBK_layer (DEF_layer); + + /* This is one of the layer geometry. */ + LV_width = DEF2MBK_length ((long)(pt2->x) - (long)(pt1->x)); + LV_height = DEF2MBK_length ((long)(pt2->y) - (long)(pt1->y)); + + LV_width = ABS(LV_width); + LV_height = ABS(LV_height); + + if ( (LV_height <= MBKSCALE(2)) + && (LV_width <= MBKSCALE(2))) { + LV_width = 0; + LV_height = 0; + } + } else { + /* This is the cut layer. */ + LV_VIA = DEF2MBK_dataCut (DEF_layer); + + LV_flags |= F_VIA_CUT; + } + + def_free_pt (pt1); + def_free_pt (pt2); + free (layer_name); +} + + +/* ------------------------------------------------------------------ + * Function : "def_via_stmt_pattern()". + */ + +extern void def_via_stmt_pattern(pattern_name) + char *pattern_name; +{ + LV_flags |= F_VIA_PATTERN; + + free (pattern_name); +} + + +/* ------------------------------------------------------------------ + * Function : "def_via_end()". + */ + +extern void def_via_end() +{ + if (!(LV_flags & F_VIA_CUT)) + LV_VIA = getTurnVIA (LV_layer); + + mprintf2 (" - \"%20s\" id %02d %5ldx%-5ld.\n", + LV_modelName, LV_VIA, LV_width, LV_height); + + addDataVIA (LV_modelName, LV_VIA, LV_width, LV_height); + + LV_flags = 0; +} + + +/* ------------------------------------------------------------------ + * Function : "def_start_comps()". + */ + + +extern void def_start_comps(number) + double number; +{ + LV_numObjects = (long)number; + LV_numObjectsRead = 0L; +} + + +/* ------------------------------------------------------------------ + * Function : "def_end_comps()". + */ + +extern void def_end_comps(void) +{ + if (LV_numObjects != LV_numObjectsRead) { + warnMBK ("DEFloadlophig"); + wprintf ("Invalid components number : %d, (%d read)", + LV_numObjects, LV_numObjectsRead); + } +} + + +/* ------------------------------------------------------------------ + * Function : "def_comp_start()". + */ + +extern void def_comp_start(char *ins_name, char *cell_name) +{ + LV_numObjectsRead++; + + if (LV_pPhFig) { + /* Coordinates and symetry will be filled by "comp_options()". */ + LV_pPhIns = addphins (LV_pPhFig, cell_name, ins_name, NOSYM, 0, 0); + } + + if (LV_pLoFig) { + /* Assignement of signals to terminals will be done in the "net" + * section. + */ + addloins_noSig (LV_pLoFig, ins_name, getlofig (cell_name, 'P')); + } + + free ( ins_name); + free (cell_name); +} + + +/* ------------------------------------------------------------------ + * Function : "def_comp_net_list()". + */ + +extern void def_comp_net_list(char *name) +{ +} + + +/* ------------------------------------------------------------------ + * Function : "def_comp_type()". + */ + +extern void def_comp_type(pt, orient) + struct pt *pt; + double orient; +{ + if (LV_pPhFig) { + if (!IS_XY_PT (pt)) { + errMBK ("defloadlophfig"); + eprintf ("\n Invalid coordinate '*' for instance placement \"%s\"\n", + LV_pPhIns->INSNAME); + eprintf (" at line %ld.\n", yylineno); + EXIT (1); + } + + LV_pPhIns->XINS = DEF2MBK_length ((long)(pt->x)); + LV_pPhIns->YINS = DEF2MBK_length ((long)(pt->y)); + LV_pPhIns->TRANSF = DEF2MBK_transf (orient); + } + + def_free_pt (pt); +} + + +/* ------------------------------------------------------------------ + * Function : "def_start_nets()". + */ + + +extern void def_start_nets(double number) +{ + LV_numObjects = (long)number; + LV_numObjectsRead = 0L; + + mprintf1 (" o Reading NETS section (%ld nets)\n", LV_numObjects); +} + + +/* ------------------------------------------------------------------ + * Function : "def_end_nets()". + */ + +extern void def_end_nets(void) +{ + if (LV_numObjects != LV_numObjectsRead) { + warnMBK ("DEFloadlophig"); + wprintf ("Invalid net number : %d, (%d read)", + LV_numObjects, LV_numObjectsRead); + } +} + + +/* ------------------------------------------------------------------ + * Function : "def_net_start()". + */ + +extern void def_net_start(char *name) +{ + struct authelem *pElem; + + + LV_numObjectsRead++; + LV_modelName = DEF2MBK_name (name); + + mprintf2 (" - \"%s\"\n", LV_modelName); + + if ((pElem = searchauthelem (LV_htPin, LV_modelName)) != NULL) { + /* The terminal name no longer override the net name. But we keep + * the pin hash table because we must know if the net is external + * or internal (i.e. the layer is ALU or CALU. + * + * LV_modelName = LV_tPin[pElem->VALUE].pinName; + */ + LV_flags = F_SEG_PIN; + if (LV_pLoFig) { + LV_pLoSig = getlosig (LV_pLoFig, pElem->VALUE); + } + } else { + /* This not is not linked to a terminal. So it has not been created + * while reading the PIN section. We do it now. + */ + if (LV_pLoFig) { + LV_pLoSig = addlosig (LV_pLoFig, + LV_mSig++, + addchain (NULL, (void*)LV_modelName), + INTERNAL); + } + LV_flags = 0L; + } + + free (name); +} + + +/* ------------------------------------------------------------------ + * Function : "def_path_start()". + */ + +extern void def_path_start(layer_name) + char *layer_name; +{ + char *DEF_layer; + + + DEF_layer = namealloc (layer_name); + + LV_layer = DEF2MBK_layer (DEF_layer); + LV_width = DEF2MBK_layerWidth (DEF_layer); + LV_flags |= F_SEG_INITIAL; + + free (layer_name); +} + + +/* ------------------------------------------------------------------ + * Function : "def_path_item_via()". + */ + +extern void def_path_item_via(via_name) + char *via_name; +{ + char *DEF_viaLayer; + dataVIA_t *pDataVIA; + authelem *pElem; + phvia_list *pPhvia; + + + /* This a VIA and maybe a layer change. */ + DEF_viaLayer = namealloc (via_name); + + + if (LV_flags & F_SEG_INITIAL) { + errMBK ("defloadlophfig"); + eprintf ("Net path cannot begin by a VIA at line %ld", yylineno); + EXIT (1); + } + + + pDataVIA = DEF2MBK_dataVIA (DEF_viaLayer); + LV_layer = getAltVIALayer (pDataVIA->VIA, LV_layer); + + if (!(LV_flags & F_SEG_SPECIAL)) { + LV_width = MBK_layerWidth (LV_layer); + } + + + if (LV_pPhFig && !(LV_flags & F_SEG_BLOCKAGE)) { + pPhvia = addphvia(LV_pPhFig, + pDataVIA->VIA, + LV_lastX, + LV_lastY, + pDataVIA->width, + pDataVIA->height, + LV_modelName); + + if (!getmvia (LV_ptLoseg->tMVIA, pPhvia)) { + LV_ptLoseg->tMVIA = addmvia (LV_ptLoseg->tMVIA, pPhvia); + } + + pElem = gettlosegitem (LV_ptLoseg, LV_modelName); + + LV_ptLoseg->tLoseg[pElem->VALUE] = addloseg ( + LV_ptLoseg->tLoseg[pElem->VALUE], LOSEG_VIA, (void*)pPhvia); + } + + + free (via_name); +} + + +/* ------------------------------------------------------------------ + * Function : "def_path_item_pt()". + */ + +extern void def_path_item_pt(pt) + struct pt *pt; +{ + long curX, curY; + char *sigName, powerName[64]; + authelem *pElem; + phseg_list *pPhSeg; + + + if (IS_X_PT(pt)) { curX = DEF2MBK_length ((long)pt->x); } + else { curX = LV_lastX; } + + + if (IS_Y_PT(pt)) { curY = DEF2MBK_length ((long)pt->y); } + else { curY = LV_lastY; } + + + if (LV_flags & F_SEG_INITIAL) { + if (!IS_XY_PT(pt)) { + errMBK ("defloadlophfig"); + eprintf ("Invalid first net path point at line %ld", yylineno); + EXIT (1); + } + + LV_flags &= ~F_SEG_INITIAL; + } else { + if (LV_pPhFig) { + if ( (LV_defFlags & F_DEF_SPLIT_POWER) + && (isvdd (LV_modelName) || isvss (LV_modelName))) { + sigName = powerName; + sprintf (sigName, + "%s.%ld", + LV_modelName, + (curY - LV_pPhFig->XAB1 + MBKSCALE(25)) / MBKSCALE(50)); + } else + sigName = LV_modelName; + + if (!(LV_flags & F_SEG_BLOCKAGE)) { + pPhSeg = addphseg (LV_pPhFig, + (LV_flags & F_SEG_PIN) ? getCALU (LV_layer) + : LV_layer, + LV_width, + LV_lastX, + LV_lastY, + curX, + curY, + sigName); + + pElem = gettlosegitem (LV_ptLoseg, sigName); + + LV_ptLoseg->tLoseg[pElem->VALUE] = addloseg ( + LV_ptLoseg->tLoseg[pElem->VALUE], LOSEG_SEG, (void*)pPhSeg); + } + } + } + + + LV_lastX = curX; + LV_lastY = curY; + + def_free_pt (pt); +} + + +/* ------------------------------------------------------------------ + * Function : "def_opt_width()". + */ + + extern void def_opt_width(number) + double number; +{ + LV_width = DEF2MBK_length ((long)number); +} + + +/* ------------------------------------------------------------------ + * Function : "def_net_conn_start()". + */ + +extern void def_net_conn_start(char *ins_name, char *pin_name) +{ + if (LV_pLoFig) { + if (strcmp (ins_name, "PIN")) { + addlosig_insCon (getloins (LV_pLoFig, + ins_name), + DEF2MBK_name (pin_name), + LV_pLoSig); + + free (ins_name); + } + } + + + free (pin_name); +} + + +/* ------------------------------------------------------------------ + * Function : "def_net_conn_opt_synthesized()". + */ + +extern void def_net_conn_opt_synthesized() +{ +} + + +/* ------------------------------------------------------------------ + * Function : "def_start_snets()". + */ + + +extern void def_start_snets(double number) +{ + LV_numObjects = (long)number; + LV_numObjectsRead = 0L; + + mprintf1 (" o Reading SPECIALNETS section.\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "def_end_snets()". + */ + +extern void def_end_snets(void) +{ + if (LV_numObjects != LV_numObjectsRead) { + warnMBK ("DEFloadlophig"); + wprintf ("Invalid special nets number : %d, (%d read)", + LV_numObjects, LV_numObjectsRead); + } +} + + +/* ------------------------------------------------------------------ + * Function : "def_snet_start()". + */ + +extern void def_snet_start(char *name) +{ + struct authelem *pElem; + + + LV_numObjectsRead++; + LV_modelName = namealloc (name); + LV_flags = F_SEG_SPECIAL; + + if (LV_modelName == LV_blockageName) { + /* This is a special net named "_BLOCKAGE_RESERVED" used to forbid + * the corners of the design when placing the IO pins. Must not be + * driven in the MBK data-base. + */ + LV_flags |= F_SEG_BLOCKAGE; + } else { + if ((pElem = searchauthelem (LV_htPin, LV_modelName)) != NULL) { + /* The terminal name no longer override the net name. But we keep + * the pin hash table because we must know if the net is external + * or internal (i.e. the layer is ALU or CALU. + * + * LV_modelName = LV_tPin[pElem->VALUE].pinName; + */ + LV_flags |= F_SEG_PIN; + if (LV_pLoFig) { + LV_pLoSig = getlosig (LV_pLoFig, pElem->VALUE); + } + } else { + /* This not is not linked to a terminal. So it has not been created + * while reading the PIN section. We do it now. + */ + if (LV_pLoFig) { + LV_pLoSig = addlosig (LV_pLoFig, + LV_mSig++, + addchain (NULL, + (void*)DEF2MBK_name(LV_modelName)), + INTERNAL); + } + LV_flags = 0L; + } + } + + mprintf2 (" - \"%s\".\n", LV_modelName); + + + free (name); +} + + +/* ------------------------------------------------------------------ + * Function : "def_snet_conn_start()". + */ + +extern void def_snet_conn_start(char *ins_name, char *pin_name) +{ + if (LV_pLoFig) { + if (strcmp (ins_name, "PIN")) { + addlosig_insCon (getloins (LV_pLoFig, + ins_name), + pin_name, + LV_pLoSig); + + free (ins_name); + } + } + + + free (pin_name); +} + + +/* ------------------------------------------------------------------ + * Function : "def_snet_conn_opt_synthesized()". + */ + +extern void def_snet_conn_opt_synthesized() +{ +} + + +/* ------------------------------------------------------------------ + * Function : "def_snet_conn_opt_synthesized()". + */ + +extern void def_parse_error(str) + char *str; +{ + errMBK ("DEFloadphlofig"); + eprintf ("%s line %d.\n", str, yylineno); + EXIT (1); +} + + +/* ------------------------------------------------------------------ + * Function : "def_alloc_pt()". + */ + +extern struct pt *def_alloc_pt(x, y) + double x, y; +{ + struct pt *pt; + + + pt = (struct pt*)malloc (sizeof (struct pt)); + + if (!pt) { + errMBK ("DEFloadlophig"); + eprintf ("Not enougth memory in \"def_alloc_pt()\"!\n"); + EXIT (1); + } + + pt->x = x; + pt->y = y; + + return (pt); +} + + +/* ------------------------------------------------------------------ + * Function : "def_free_pt()". + */ + +extern void def_free_pt(pt) + struct pt *pt; +{ + free (pt); +} + + +/* ------------------------------------------------------------------ + * Function : "initDataTables()". + */ + +static void initDataTables() +{ + int iData; + + + for (iData = 0; iData < SIZE_TDATALAYER; iData++) { + tDataLayer[iData].flags = 0L; + } + + for (iData = 0; iData < SIZE_TDATACUT; iData++) { + tDataCut[iData].flags = 0L; + } + + for (iData = 0; iData < SIZE_TDATAVIA; iData++) { + tDataVIA[iData].flags = 0L; + } +} + + +/* ------------------------------------------------------------------ + * Function : "setDataLayer()". + */ + +static void setDataLayer(aN, aName, aLayer, aCLayer, aWidth) + int aN; + char *aName; + char aLayer; + char aCLayer; + long aWidth; +{ + tDataLayer[aN].name = namealloc (aName); + tDataLayer[aN].layer = aLayer; + tDataLayer[aN].clayer = aCLayer; + tDataLayer[aN].width = aWidth; + tDataLayer[aN].flags |= F_DATA_SET; +} + + +/* ------------------------------------------------------------------ + * Function : "setDataCut()". + */ + +static void setDataCut(aN, aName, aCut) + int aN; + char *aName; + char aCut; +{ + tDataCut[aN].name = namealloc (aName); + tDataCut[aN].VIA = aCut; + tDataCut[aN].flags |= F_DATA_SET; +} + + +/* ------------------------------------------------------------------ + * Function : "addDataVIA()". + */ + +static void addDataVIA(aName, aCut, aWidth, aHeight) + char *aName; + char aCut; + long aWidth; + long aHeight; +{ + if (LV_mVIA > SIZE_TDATAVIA) { + errMBK ("DEFloadlophig"); + eprintf ("VIA table overfow (more than %d VIAs).\n", SIZE_TDATAVIA); + EXIT (1); + } + + tDataVIA[LV_mVIA].name = namealloc (aName); + tDataVIA[LV_mVIA].VIA = aCut; + tDataVIA[LV_mVIA].flags |= F_DATA_SET; + tDataVIA[LV_mVIA].width = aWidth; + tDataVIA[LV_mVIA].height = aHeight; + + LV_mVIA++; +} + + +/* ------------------------------------------------------------------ + * Function : "DEF2MBK_dataVIA()". + */ + +static dataVIA_t *DEF2MBK_dataVIA(aName) + char *aName; +{ + int iDV; + + + for (iDV = 0; iDV < SIZE_TDATAVIA; iDV++) { + if ( (tDataVIA[iDV].flags & F_DATA_SET) + && (tDataVIA[iDV].name == aName)) { + return (&(tDataVIA[iDV])); + } + } + + errMBK ("DEFloadphlofig"); + eprintf ("\n Unknown DEF VIA name \"%s\" at line %d.\n", + aName, yylineno); + EXIT (1); + + /* Only to shut up GCC... */ + return (NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF_isLayer()". + */ + +static long DEF_isLayer(aName) + char *aName; +{ + int iDL; + + + for (iDL = 0; iDL < SIZE_TDATALAYER; iDL++) { + if ( (tDataLayer[iDL].flags & F_DATA_SET) + && (tDataLayer[iDL].name == aName)) { + return (TRUE); + } + } + + return (FALSE); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF2MBK_layer()". + */ + +static char DEF2MBK_layer(aName) + char *aName; +{ + int iDL; + + + for (iDL = 0; iDL < SIZE_TDATALAYER; iDL++) { + if ( (tDataLayer[iDL].flags & F_DATA_SET) + && (tDataLayer[iDL].name == aName)) { + return (tDataLayer[iDL].layer); + } + } + + errMBK ("DEFloadphlofig"); + eprintf ("\n Unknown DEF layer name \"%s\" at line %d.\n", + aName, yylineno); + EXIT (1); + + /* Only to shut up GCC... */ + return ('\0'); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF2MBK_layerWidth()". + */ + +static long DEF2MBK_layerWidth(aName) + char *aName; +{ + int iDL; + + + for (iDL = 0; iDL < SIZE_TDATALAYER; iDL++) { + if ( (tDataLayer[iDL].flags & F_DATA_SET) + && (tDataLayer[iDL].name == aName)) { + return (tDataLayer[iDL].width); + } + } + + errMBK ("DEFloadphlofig"); + eprintf ("\n Unknown DEF layer name \"%s\" at line %d.\n", + aName, yylineno); + EXIT (1); + + /* Only to shut up GCC... */ + return (0L); +} + + +/* ------------------------------------------------------------------ + * Function : "MBK_layerWidth()". + */ + +static long MBK_layerWidth(aLayer) + char aLayer; +{ + int iDL; + + + for (iDL = 0; iDL < SIZE_TDATALAYER; iDL++) { + if ( (tDataLayer[iDL].flags & F_DATA_SET) + && ( (tDataLayer[iDL].layer == aLayer) + || (tDataLayer[iDL].clayer == aLayer))) { + return (tDataLayer[iDL].width); + } + } + + errMBK ("DEFloadphlofig"); + eprintf ("\n Unknown MBK layer id \"%d\" at line %d.\n", + (int)aLayer, yylineno); + EXIT (1); + + /* Only to shut up GCC... */ + return (0L); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF2MBK_dataCut()". + */ + +static char DEF2MBK_dataCut(aName) + char *aName; +{ + int iDC; + + + for (iDC = 0; iDC < SIZE_TDATACUT; iDC++) { + if ( (tDataCut[iDC].flags & F_DATA_SET) + && (tDataCut[iDC].name == aName)) { + return (tDataCut[iDC].VIA); + } + } + + errMBK ("DEFloadphlofig"); + eprintf ("\n Unknown DEF cut layer name \"%s\" at line %d.\n", + aName, yylineno); + EXIT (1); + + /* Only to shut up GCC... */ + return ('\0'); +} + + +/* ------------------------------------------------------------------ + * Function : "orderCoord()". + */ + +static void orderCoord (aX1, aX2) + long *aX1, *aX2; +{ + long tmp; + + + if (*aX1 > *aX2) + { tmp = *aX1; *aX1 = *aX2; *aX2 = tmp; } +} + + +/* ------------------------------------------------------------------ + * Function : "DEF_pinxyflat()". + */ + +static void DEF_pinxyflat(apX_flat, apY_flat, aX, aY, aX_ins, aY_ins, aT) + long *apX_flat, *apY_flat; + long aX , aY; + long aX_ins , aY_ins; + char aT; +{ + switch (aT) { + /* DEF : N (North). */ + case NOSYM : + *apX_flat = aX_ins + aX; + *apY_flat = aY_ins + aY; + break; + + /* DEF : FN (Flipped North). */ + case SYM_X : + *apX_flat = aX_ins - aX; + *apY_flat = aY_ins + aY; + break; + + /* DEF : S (Flipped South). */ + case SYM_Y : + *apX_flat = aX_ins + aX; + *apY_flat = aY_ins - aY; + break; + + /* DEF : S (South). */ + case SYMXY : + *apX_flat = aX_ins - aX; + *apY_flat = aY_ins - aY; + break; + + /* DEF : W (West). */ + case ROT_P : + *apX_flat = aX_ins - aY; + *apY_flat = aY_ins + aX; + break; + + /* DEF : E (East). */ + case ROT_M : + *apX_flat = aX_ins + aY; + *apY_flat = aY_ins - aX; + break; + + /* DEF : FP (Flipped West). */ + case SY_RP : + *apX_flat = aX_ins + aY; + *apY_flat = aY_ins + aX; + break; + + /* DEF : FE (Flipped East). */ + case SY_RM : + *apX_flat = aX_ins - aY; + *apY_flat = aY_ins - aX; + break; + } +} + + +/* ------------------------------------------------------------------ + * Function : "LEF2MBK_setData()". + */ + +static void LEF2MBK_setData() +{ + setDataLayer (0, "L_ALU1", ALU1, CALU1, MBKSCALE(1)); + setDataLayer (1, "L_ALU2", ALU2, CALU2, MBKSCALE(2)); + setDataLayer (2, "L_ALU3", ALU3, CALU3, MBKSCALE(2)); + setDataLayer (3, "L_ALU4", ALU4, CALU4, MBKSCALE(2)); + setDataLayer (4, "L_ALU5", ALU5, CALU5, MBKSCALE(2)); + setDataLayer (5, "L_ALU6", ALU6, CALU6, MBKSCALE(2)); + setDataLayer (6, "L_ALU7", ALU7, CALU7, MBKSCALE(2)); + setDataLayer (7, "L_ALU8", ALU8, CALU8, MBKSCALE(2)); + setDataLayer (8, "L_ALU9", ALU9, CALU9, MBKSCALE(2)); + + setDataCut (0, "L_CONT", CONT_POLY); + setDataCut (1, "L_VIA1", CONT_VIA); + setDataCut (2, "L_VIA2", CONT_VIA2); + setDataCut (3, "L_VIA3", CONT_VIA3); + setDataCut (4, "L_VIA4", CONT_VIA4); + setDataCut (5, "L_VIA5", CONT_VIA5); + setDataCut (6, "L_VIA6", CONT_VIA6); + setDataCut (7, "L_VIA7", CONT_VIA7); + setDataCut (8, "L_VIA8", CONT_VIA8); +} + + +/* ------------------------------------------------------------------ + * Function : "defloadlophig()". + */ + +extern void defloadlophfig (apLoFig, apPhFig, aName, aMode, aVL, aFlags) + lofig_list *apLoFig; + phfig_list *apPhFig; + char *aName; + char aMode; + long aVL; + long aFlags; +{ + long isRouted, iLoseg, type; + void *MBKobj; + struct ePow_s *plPow; + struct eLoseg_s *pLoseg; + + + LV_pPhFig = apPhFig; + LV_pLoFig = apLoFig; + LV_mode = aMode; + LV_name = namealloc (aName); + LV_mSig = 0L; + LV_defFlags = aFlags; + + LV_blockageName = namealloc ("_BLOCKAGE_RESERVED"); + + setVL (aVL); + + + initDataTables (); + LEF2MBK_setData (); + + + if (!LV_pLoFig) { + errMBK ("defloadlophfig"); + eprintf ("\n lofig is not allocated"); + eprintf (" while loading \"%s.%s\"\n", aName, LV_IN_PH); + EXIT (1); + } + + if (LV_mode != 'A') { + errMBK ("defloadlophfig"); + eprintf ("\n Unsupported load mode '%c'", aMode); + eprintf (" while loading \"%s.%s\"\n", aName, LV_IN_PH); + EXIT (1); + } + + yyin = mbkfopen (LV_name, LV_IN_PH, READ_TEXT); + if (!yyin) { + errMBK ("defloadlophfig"); + eprintf ("\n Unable to open file \"%s.%s\"\n", aName, LV_IN_PH); + EXIT (1); + } + + + mprintf2 ("\n"); + + LV_ptLoseg = addtloseg (LV_pPhFig); + + yylineno = 1; + yydebug = 0; + yyparse (); + + destroyauthtable (LV_htPin); + free (LV_tPin); + + mprintf2 ("\n"); + + + if (fclose (yyin)) { + warnMBK ("defloadlophfig"); + wprintf ("\n Unable to close file \"%s.%s\"\n", aName, LV_IN_PH); + } + + + delfeed (LV_pLoFig); + checkLofig (LV_pLoFig); + + if (LV_pPhFig) { + if (LV_defFlags & F_DEF_NO_IOS) { + __DBG( fprintf (stderr, "\n o Removing fake IO\'s.\n"); ) + for (iLoseg = 0; iLoseg < LV_ptLoseg->sigNB; iLoseg++) { + isRouted = FALSE; + + for (pLoseg = LV_ptLoseg->tLoseg[iLoseg]; + pLoseg != NULL; pLoseg = pLoseg->next) { + switch (pLoseg->type) { + case LOSEG_VIA: + __DBG( + fprintf (stderr, " - \"%s\" is routed.\n", + ((struct phvia*)(pLoseg->MBKobj))->NAME); + ) + isRouted = TRUE; + break; + case LOSEG_SEG: + __DBG( + fprintf (stderr, " - \"%s\" is routed.\n", + ((struct phseg*)(pLoseg->MBKobj))->NAME); + ) + isRouted = TRUE; + break; + case LOSEG_CON: + case LOSEG_SEGCON: + break; + } + + if (isRouted) break; + } + + /* If There is only terminal related objects : delete them. */ + if (!isRouted) { + __DBG( fprintf (stderr, " - Removing ?\n"); ) + for (pLoseg = LV_ptLoseg->tLoseg[iLoseg]; pLoseg != NULL; ) { + __DBG( fprintf (stderr, " - Removing loseg item.\n"); ) + type = pLoseg->type; + MBKobj = pLoseg->MBKobj; + __DBG( fprintf (stderr, " - MBKobj := %p.\n", MBKobj); ) + + pLoseg = delloseg (pLoseg); + + switch (type) { + case LOSEG_VIA: + delphvia (LV_pPhFig, (struct phvia*)MBKobj); + break; + case LOSEG_CON: + __DBG( + fprintf (stderr, " - Removing MBK phcon := "); + fprintf (stderr, "\"%s\".\n", ((struct phcon*)MBKobj)->NAME); + ) + + delphcon (LV_pPhFig, (struct phcon*)MBKobj); + break; + case LOSEG_SEG: + case LOSEG_SEGCON: + __DBG( + fprintf (stderr, " - Removing MBK phseg := "); + fprintf (stderr, "\"%s\".\n", ((struct phseg*)MBKobj)->NAME); + ) + delphseg (LV_pPhFig, (struct phseg*)MBKobj); + break; + } + } + + LV_ptLoseg->tLoseg[iLoseg] = NULL; + } + } + } + + if (!(LV_defFlags & F_DEF_NO_INTERF)) { + long powFlags; + + + mprintf1 (" o Copying up CALUx terminal segments.\n"); + copyUpCALU (LV_pLoFig, LV_pPhFig, 0); + + mprintf1 (" o Adding power supplies terminals.\n"); + + + powFlags = 0L; + if (LV_defFlags & F_DEF_MERGE_TERM) powFlags = F_POWER_MERGE; + + plPow = buildPow (LV_pPhFig, ALU1, C_POWER_HORIZONTAL, ""); + powToCon (LV_pPhFig, ALU1, C_POWER_HORIZONTAL, plPow, powFlags); + + plPow = buildPow (LV_pPhFig, ALU3, C_POWER_VERTICAL, ""); + powToCon (LV_pPhFig, ALU3, C_POWER_VERTICAL, plPow, powFlags); + } + } +} diff --git a/alliance/src/sea/src/DEF_actions.h b/alliance/src/sea/src/DEF_actions.h new file mode 100644 index 00000000..4a61fe50 --- /dev/null +++ b/alliance/src/sea/src/DEF_actions.h @@ -0,0 +1,108 @@ +/* + * $Author: jpc $ + * $Id: DEF_actions.h,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * $Date: 2002/04/25 16:16:20 $ + */ + +#ifndef __deffunc_h +#define __deffunc_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEF_NOSYM 0x0000 +#define DEF_SYM_X 0x0001 +#define DEF_SYM_Y 0x0002 +#define DEF_ROT_P 0x0004 +#define DEF_ROT_M 0x0008 + +#define DEF_N (DEF_NOSYM) +#define DEF_S (DEF_SYM_X | DEF_SYM_Y) +#define DEF_W (DEF_ROT_P) +#define DEF_E (DEF_ROT_M) +#define DEF_FN (DEF_SYM_X) +#define DEF_FS (DEF_SYM_Y) +#define DEF_FW (DEF_SYM_Y | DEF_ROT_M) +#define DEF_FE (DEF_SYM_Y | DEF_ROT_P) + +#define DEF_INPUT 10 +#define DEF_OUTPUT 11 +#define DEF_INOUT 12 +#define DEF_FEEDTHRU 13 + +struct pt { double x, y; }; + +extern void def_design_name(char *name); +extern void def_tech_name(char *name); +extern void def_end_design(void); + +extern void def_units(double number); + +extern void def_die_area(struct pt *ab1, struct pt *ab2); + +extern void def_row_rule(char *row_name, + char *row_type, + double x, + double y, + double orient, + double do_number, + double by_number, + double step_x, + double step_y); + +extern void def_track_rule(char *axis_name, + double start, + double do_number, + double step, + char *layer_list); +extern char *def_track_layers(char *layer_name, char *layer_list); + +extern void def_start_pins(double number); +extern void def_end_pins(void); +extern void def_pin_start(char *pin_name, char *net_name); +extern void def_pin_options(void); +extern void def_pin_option_direction(double dir); +extern void def_pin_option_place(struct pt *pt, double orient); +extern void def_pin_option_layer(char *layer_name, struct pt *pt1, struct pt *pt2); + +extern void def_start_vias(double number); +extern void def_end_vias(void); +extern void def_via_start(char *via_name); +extern void def_via_stmt_rect(char *layer_name, struct pt *pt1, struct pt *pt2); +extern void def_via_stmt_pattern(char *pattern_name); +extern void def_via_end(void); + +extern void def_start_comps(double number); +extern void def_end_comps(void); +extern void def_comp_start(char *ins_name, char *cell_name); +extern void def_comp_net_list(char *name); +extern void def_comp_type(struct pt* pt, double orient); + +extern void def_start_nets(double number); +extern void def_end_nets(void); +extern void def_net_start(char *name); +extern void def_net_conn_start(char *ins_name, char *pin_name); +extern void def_net_conn_opt_synthesized(void); +extern void def_path_start(char *layer_name); +extern void def_path_item_via(char *via_name); +extern void def_path_item_pt(struct pt *pt1); +extern void def_opt_width(double number); + +extern void def_start_snets(double number); +extern void def_end_snets(void); +extern void def_snet_start(char *name); +extern void def_snet_conn_start(char *ins_name, char *pin_name); +extern void def_snet_conn_opt_synthesized(void); + +extern struct pt *def_alloc_pt(double x, double y); +extern void def_free_pt(struct pt *pt); + +extern void def_parse_error(char *str); + + +#ifdef __cplusplus +} +#endif + +#endif /* __deffunc_h */ diff --git a/alliance/src/sea/src/DEF_drive.c b/alliance/src/sea/src/DEF_drive.c new file mode 100644 index 00000000..a86f1ed6 --- /dev/null +++ b/alliance/src/sea/src/DEF_drive.c @@ -0,0 +1,1699 @@ +/* + * $Id: DEF_drive.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./DEF_drive.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "debugoff.h" +# include "util_Defs.h" +# include "DEF_drive.h" + + +/* ------------------------------------------------------------------ + * Internal types and defines. + */ + +# define C_DIRECTION_NONE ((char)0) +# define C_DIRECTION_INPUT ((char)1) +# define C_DIRECTION_OUTPUT ((char)2) +# define C_DIRECTION_TRISTATE ((char)3) +# define C_DIRECTION_INOUT ((char)4) +# define C_DIRECTION_FEEDTHRU ((char)5) + +# define C_USE_NONE ((char)0) +# define C_USE_SIGNAL ((char)1) +# define C_USE_ANALOG ((char)2) +# define C_USE_POWER ((char)3) +# define C_USE_GROUND ((char)4) +# define C_USE_CLOCK ((char)5) + +# define TTERM_SIZE 1024 + +# define PTYPE_PHFIG 1024 +# define PTYPE_LOFIG 1025 + +# define F_REGULAR_NET 0x00000001 +# define F_SPECIAL_NET 0x00000002 + +# define F_SEG_WIDTH 0x00000001 +# define F_SEG_STRIPE 0x00000002 + + +/* ------------------------------------------------------------------ + * Internal types. + */ + + typedef struct row_s { + char *rowName; + char *rowType; + long x; + long y; + long orient; + long doNumber; + long byNumber; + long stepX; + long stepY; + struct row_s *next; + } row_t; + + typedef struct track_s { + char axisName; + long start; + long doNumber; + long step; + char *routingLayers; + long x; + long y; + struct track_s *next; + } track_t; + + typedef struct blockage_s { + long x; + long y; + long width; + long height; + struct blockage_s *next; + } blockage_t; + + +/* ------------------------------------------------------------------ + * Internal variables. + */ + + static FILE *DEF_FILE; + static long LV_Flags = 0L; + static long LV_localFlags = 0L; + static char *LV_name; + static struct lofig *LV_lofig; + static struct phfig *LV_phfig; + static struct row_s *LV_row; + static struct track_s *LV_track; + static struct blockage_s *LV_blockage; + static struct authtable *LV_htTerm; + static char routingLayers3[256] = "L_ALU1 L_ALU2 L_ALU3"; + static char routingLayers4[256] = + "L_ALU1 L_ALU2 L_ALU3 L_ALU4"; + static char routingLayers6[256] = + "L_ALU1 L_ALU2 L_ALU3 L_ALU4 L_ALU5 L_ALU6"; + + +/* ------------------------------------------------------------------ + * Local functions. + */ + + static struct phins *getphinslink __FP((struct loins *apLoins)); + static void buildphinslinks __FP((void)); + static void buildtterm __FP((void)); + static void freetterm __FP((void)); + static void freephinslinks __FP((void)); + static void swapOrient __FP((char *apSameOrient, + char *apOppositeOrient)); + static char normOrient __FP((char aOrient)); + static long orientPhfig __FP((struct phfig *apPhfig, + char *apSameOrient, + char *apOppositeOrient)); + static char *DIRtoa __FP((char acDIR)); + static char *USEtoa __FP((char acUSE)); + static char *strLCat __FP((char *asLine, + char *asEl, + long *aplLine, + long alMax)); + static void fprintDIEAREA __FP((void)); + static struct row_s *newrow __FP((void)); + static void freerow __FP((void)); + static void ref2ROW __FP((void)); + static struct row_s *getBaseRow __FP((long aX, + long aY, + char aOrient)); + static void fprintROWS __FP((void)); + static struct track_s *newtrack __FP((void)); + static void freetrack __FP((void)); + static void ref2TRACK __FP((void)); + static void fprintTRACKS __FP((void)); + static struct blockage_s *newblockage __FP((void)); + static void freeblockage __FP((void)); + static void ref2BLOCKAGE __FP((void)); + static void fprintBLOCKAGE __FP((void)); + static void fprintVIAMATRIX __FP((char aType, + long aWidth, + long aHeight)); + static void fprintVIAS __FP((void)); + static long checkPhins __FP((struct phins *apPhins)); + static void fprintCOMPONENTS __FP((void)); + static void fprintPIN __FP((struct locon *apLocon, + struct phcon *apPhcon, + char *asState)); + static void fprintPINS __FP((void)); + static void fprintWIRESEG __FP((struct phseg *apPhseg, + long aFlags)); + static void fprintWIREVIA __FP((struct phvia *apPhvia, + long aFlags)); + static void fprintWIRES __FP((struct losig *apLosig)); + static void fprintNET __FP((struct losig *apLoSig, + char aUse)); + static void fprintNETS __FP((void)); + static void fprintSPECIALNETS __FP((void)); + static void fprintDEF __FP((void)); + + +/* + * /----------------------------------------------------------------\ + * | Functions Definitions | + * \----------------------------------------------------------------/ + */ + +/* ------------------------------------------------------------------ + * Function : "getphinslink()". + */ + +static struct phins *getphinslink(apLoins) + struct loins *apLoins; +{ + struct ptype *pType; + + + if ((pType = getptype (apLoins->USER, PTYPE_PHFIG)) == NULL) + return (NULL); + + return ((struct phins*)pType->DATA); +} + + +/* ------------------------------------------------------------------ + * Function : "buildphinslinks()". + */ + +static void buildphinslinks() +{ + struct loins *pLoins; + struct phins *pPhins; + long flag; + + + flag = FALSE; + + /* Check if there is a physical figure. */ + if (!LV_phfig) return; + + for (pLoins = LV_lofig->LOINS; pLoins != NULL; pLoins = pLoins->NEXT) { + if ((pPhins = findphins (LV_phfig, pLoins->INSNAME))) { + if (pLoins->FIGNAME != pPhins->FIGNAME) { + flag = TRUE; + + eprinth (NULL); + eprintf ("Instances of \"%s\" have NOT the same physical", + pLoins->INSNAME); + eprintf (" and logical model :\n"); + eprintf (" logical := \"%s\"", pLoins->FIGNAME); + eprintf (" physical := \"%s\".\n", pPhins->FIGNAME); + + continue; + } + + pLoins->USER = addptype (pLoins->USER, PTYPE_PHFIG, (void*)pPhins); + pPhins->USER = addptype (pPhins->USER, PTYPE_LOFIG, (void*)pLoins); + } + } + + + /* Check if all physical instances are in the netlist. */ + + + for (pPhins = LV_phfig->PHINS; pPhins != NULL; pPhins = pPhins->NEXT) { + if (!getptype (pPhins->USER, PTYPE_LOFIG)) { + if (!flag) { + /* Print the head error message. */ + flag = TRUE; + + eprinth (NULL); + eprintf ("The following physical instances are not in the"); + eprintf (" netlist :\n"); + } + + eprintf ("- \"%s\" (model \"%s\").\n", + pPhins->INSNAME, pPhins->FIGNAME); + } + } + + + if (flag) EXIT (1); +} + + +/* ------------------------------------------------------------------ + * Function : "freephinslinks()". + */ + +static void freephinslinks() +{ + struct loins *pLoins; + struct phins *pPhins; + + + /* Check if there is a physical figure. */ + if (!LV_phfig) return; + + for (pLoins = LV_lofig->LOINS; pLoins != NULL; pLoins = pLoins->NEXT) { + if (pLoins->USER) + pLoins->USER = delptype (pLoins->USER, PTYPE_PHFIG); + } + + + for (pPhins = LV_phfig->PHINS; pPhins != NULL; pPhins = pPhins->NEXT) { + if (pPhins->USER) + pPhins->USER = delptype (pPhins->USER, PTYPE_LOFIG); + } +} + + +/* ------------------------------------------------------------------ + * Function : "buildtterm()". + */ + +static void buildtterm() +{ + struct locon *pLocon; + + + LV_htTerm = createauthtable (TTERM_SIZE); + + for (pLocon = LV_lofig->LOCON; pLocon != NULL; pLocon = pLocon->NEXT) { + addauthelem (LV_htTerm, getsigname (pLocon->SIG), (long)pLocon->NAME); + } +} + + +/* ------------------------------------------------------------------ + * Function : "freetterm()". + */ + +static void freetterm() +{ + destroyauthtable (LV_htTerm); +} + + + +/* ------------------------------------------------------------------ + * Function : "swapOrient()". + */ + +static void swapOrient(apSameOrient, apOppositeOrient) + char *apSameOrient; + char *apOppositeOrient; +{ + char tmpOrient; + + tmpOrient = *apSameOrient; + *apSameOrient = *apOppositeOrient; + *apOppositeOrient = tmpOrient; +} + + +/* ------------------------------------------------------------------ + * Function : "normOrient()". + */ + +static char normOrient(aOrient) + char aOrient; +{ + char normOrient; + + + switch (aOrient) { + default: + case DEF_N: normOrient = DEF_N; break; + case DEF_FN: normOrient = DEF_N; break; + case DEF_FS: normOrient = DEF_FS; break; + case DEF_S: normOrient = DEF_FS; break; + case DEF_W: normOrient = DEF_W; break; + case DEF_FW: normOrient = DEF_W; break; + case DEF_E: normOrient = DEF_FE; break; + case DEF_FE: normOrient = DEF_FE; break; + } + + return (normOrient); +} + + +/* ------------------------------------------------------------------ + * Function : "getOppositeOrient()". + */ + +static char getOppositeOrient(aOrient) + char aOrient; +{ + char oppositeOrient; + + + switch (aOrient) { + default: + case DEF_N: oppositeOrient = DEF_FS; break; + case DEF_FN: oppositeOrient = DEF_FS; break; + case DEF_FS: oppositeOrient = DEF_N; break; + case DEF_S: oppositeOrient = DEF_N; break; + case DEF_W: oppositeOrient = DEF_FE; break; + case DEF_FW: oppositeOrient = DEF_FE; break; + case DEF_E: oppositeOrient = DEF_W; break; + case DEF_FE: oppositeOrient = DEF_W; break; + } + + return (oppositeOrient); +} + + +/* ------------------------------------------------------------------ + * Function : "orientPhfig()". + */ + +static long orientPhfig(apPhfig, apSameOrient, apOppositeOrient) + struct phfig *apPhfig; + char *apSameOrient; + char *apOppositeOrient; +{ + struct ePow_s *plPow; + long sliceHeight; + + + plPow = buildPow (apPhfig, ALU1, C_POWER_HORIZONTAL, ""); + + sliceHeight = (apPhfig->YAB2 - apPhfig->YAB1) / MBK_Y_SLICE; + + if (!plPow) { + if (LV_Flags & F_TRUST_ORIENT) { + *apSameOrient = DEF_N; + *apOppositeOrient = DEF_FS; + + return (FALSE); + } + + eprinth (NULL); + eprintf ("\n Model \"%s\" have no horizontal ALU1 power supplies.", + apPhfig->NAME); + eprintf ("\n Can't guess allowed orientations.\n"); + EXIT (1); + } + + + switch (plPow->Type) { + default: + case C_POWER_ISVSS: + *apSameOrient = DEF_N; + *apOppositeOrient = DEF_FS; + break; + case C_POWER_ISVDD: + *apSameOrient = DEF_FS; + *apOppositeOrient = DEF_N; + break; + } + + if (!(sliceHeight % 2)) + *apOppositeOrient = *apSameOrient; + + + freePow (plPow); + + return (TRUE); +} + + +/* ------------------------------------------------------------------ + * Function : "DIRtoa()". + */ + +static char *DIRtoa(acDIR) + char acDIR; +{ + switch(acDIR) { + case C_DIRECTION_NONE: return((char*)NULL); + case C_DIRECTION_INPUT: return("INPUT"); + case C_DIRECTION_OUTPUT: return("OUTPUT"); + case C_DIRECTION_TRISTATE: return("OUTPUT"); + case C_DIRECTION_INOUT: return("INOUT"); + case C_DIRECTION_FEEDTHRU: return("FEEDTHRU"); + } + return((char*)NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "USEtoa()". + */ + +static char *USEtoa(acUSE) + char acUSE; +{ + switch(acUSE) { + case C_USE_NONE: return((char*)NULL); + case C_USE_SIGNAL: return("signal"); + case C_USE_ANALOG: return("analog"); + case C_USE_POWER: return("power"); + case C_USE_GROUND: return("ground"); + case C_USE_CLOCK: return("clock"); + } + + return((char*)NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "strLCat()". + */ + +static char *strLCat(asLine, asEl, aplLine, alMax) + char *asLine, *asEl; + long *aplLine, alMax; +{ + long lCopy; + + + /* Copy the string `asEl' if there is enougth place. */ + lCopy = m_Min(alMax - *aplLine - 1, strlen(asEl)); + strncpy(asLine + *aplLine, asEl, lCopy); + *aplLine += lCopy; + + /* Terminate the string by a zero. */ + asLine[(*aplLine)] = (char)0; + + return(asLine); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintDIEAREA()". + */ + +static void fprintDIEAREA() +{ + if (LV_phfig) { + fprintf (DEF_FILE, + "\nDIEAREA ( %ld %ld ) ( %ld %ld ) ;\n", + MBK2DEF_length (LV_phfig->XAB1), + MBK2DEF_length (LV_phfig->YAB1), + MBK2DEF_length (LV_phfig->XAB2), + MBK2DEF_length (LV_phfig->YAB2)); + } +} + + +/* ------------------------------------------------------------------ + * Function : "newrow()". + */ + +static struct row_s *newrow() +{ + struct row_s *pRow; + + pRow = (row_t*)mbkalloc (sizeof (row_t)); + pRow->next = LV_row; + + return (LV_row = pRow); +} + + +/* ------------------------------------------------------------------ + * Function : "freerow()". + */ + +static void freerow() +{ + struct row_s *pRow; + + while (LV_row) { + pRow = LV_row->next; + + mbkfree (LV_row->rowName); + mbkfree (LV_row->rowType); + mbkfree (LV_row); + + LV_row = pRow; + } +} + + +/* ------------------------------------------------------------------ + * Function : "ref2ROW()". + */ + +static void ref2ROW() +{ + struct phref *pPhref; + struct row_s *pRow; + + + if (LV_phfig) { + for (pPhref = LV_phfig->PHREF; pPhref != NULL; pPhref = pPhref->NEXT) { + if (!strncmp (pPhref->NAME, "row_", 4)) { + pRow = newrow (); + + MBK2DEF_row (pPhref, + &pRow->rowName, + &pRow->rowType, + &pRow->orient, + &pRow->doNumber, + &pRow->byNumber, + &pRow->stepX, + &pRow->stepY, + &pRow->x, + &pRow->y); + } + } + } +} + + +/* ------------------------------------------------------------------ + * Function : "hasROW()". + */ + +extern long hasROW(apPhfig) + struct phfig *apPhfig; +{ + struct phref *pPhref; + + + for (pPhref = apPhfig->PHREF; pPhref != NULL; pPhref = pPhref->NEXT) { + if (!strncmp (pPhref->NAME, "row_", 4)) { + return (TRUE); + } + } + + return(FALSE); +} + + +/* ------------------------------------------------------------------ + * Function : "buildROWS()". + */ + +extern long buildROWS(apPhfig) + struct phfig *apPhfig; +{ + struct phins *pIns; + long iRow; + long rowGridX0, rowGridY0, rowGridIns, rowSizeX, rowSizeY; + char sameOrient, oppositeOrient; + char rowName[1024]; + + + if (hasROW(apPhfig)) return (FALSE); + + + pIns = NULL; + + rowGridX0 = apPhfig->XAB1; + rowGridY0 = apPhfig->YAB1; + sameOrient = DEF_N; + oppositeOrient = DEF_FS; + + rowSizeX = (apPhfig->XAB2 - apPhfig->XAB1) / MBK_X_GRID; + rowSizeY = (apPhfig->YAB2 - apPhfig->YAB1) / MBK_Y_SLICE; + + + for (pIns = apPhfig->PHINS; pIns != NULL; pIns = pIns->NEXT) { + /* Skip unpitched instances. */ + if ((pIns->XINS - apPhfig->XAB1) % MBK_X_GRID) continue; + if ((pIns->YINS - apPhfig->YAB1) % MBK_X_GRID) continue; + + if (!orientPhfig (getphfig (pIns->FIGNAME, 'A'), + &sameOrient, + &oppositeOrient)) continue; + + mprintf2 (" o Taking \"%s\" as reference for the ROW grid.\n", + pIns->INSNAME); + + rowGridX0 = apPhfig->XAB1; + rowGridY0 = apPhfig->YAB1 + + (pIns->YINS - apPhfig->YAB1) % MBK_Y_SLICE; + + rowSizeX = (apPhfig->XAB2 - apPhfig->XAB1) / MBK_X_GRID; + rowSizeY = (apPhfig->YAB2 - rowGridY0) / MBK_Y_SLICE; + + rowGridIns = (pIns->YINS - rowGridY0) / MBK_Y_SLICE; + + switch (pIns->TRANSF) { + default: + case SYM_X: + case NOSYM: + break; + case SYM_Y: + case SYMXY: + swapOrient (&sameOrient, &oppositeOrient); + break; + /* We do not allow rotated instances. */ + case ROT_P: + case ROT_M: + case SY_RP: + case SY_RM: continue; + } + + __DBG ( + fflush (stdout); + fprintf (stderr, "pIns->YINS := %ld.\n", pIns->YINS); + fprintf (stderr, "apPhfig->YAB1 := %ld.\n", apPhfig->YAB1); + fprintf (stderr, "rowGridY0 := %ld.\n", rowGridY0); + fprintf (stderr, "rowGridIns := %ld.\n", rowGridIns); + fflush (stderr); + ) + if (rowGridIns % 2) + swapOrient (&sameOrient, &oppositeOrient); + + break; + } + + + /* Restore the opposite orient, when the cell is 2*N slices tall. */ + oppositeOrient = getOppositeOrient (sameOrient); + + for (iRow = 0; iRow < rowSizeY; iRow++) { + sprintf (rowName, "ROW_%ld", iRow); + + DEF2MBK_row (apPhfig, + rowName, + "core", + (iRow % 2) ? oppositeOrient : sameOrient, + rowSizeX, + 1, + MBK2DEF_length (MBK_X_GRID), + MBK2DEF_length (MBK_Y_SLICE), + rowGridX0, + rowGridY0 + iRow * MBK_Y_SLICE + ); + } + + + return (TRUE); +} + + +/* ------------------------------------------------------------------ + * Function : "getBaseRow()". + */ + +static struct row_s *getBaseRow(aX, aY, aOrient) + long aX, aY; + char aOrient; +{ + struct row_s *pRow; + long rowMax; + char orient; + + + for (pRow = LV_row; pRow != NULL; pRow = pRow->next) { + orient = normOrient (aOrient); + + switch (aOrient) { + case DEF_N: + case DEF_FN: + case DEF_FS: + case DEF_S: + if (pRow->y != aY) continue; + rowMax = DEF2MBK_length (pRow->stepX) * pRow->doNumber; + + if ((aX < pRow->x) || (aX > pRow->x + rowMax)) continue; + + if (pRow->orient == orient) return (pRow); + break; + case DEF_W: + case DEF_E: + case DEF_FW: + case DEF_FE: + if (pRow->x != aX) continue; + rowMax = DEF2MBK_length (pRow->stepY) * pRow->byNumber; + + if ((aY < pRow->y) || (aY > pRow->y + rowMax)) continue; + + if (pRow->orient == orient) + return (pRow); + break; + } + } + + + return (NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintROWS()". + */ + +static void fprintROWS () +{ + struct row_s *pRow; + + + for (pRow = LV_row; pRow != NULL; pRow = pRow->next) { + fprintf (DEF_FILE, + "ROW %s %s %ld %ld %s DO %ld BY %ld STEP %ld %ld ;\n", + pRow->rowName, + pRow->rowType, + pRow->x, + pRow->y, + DEF_orient2a(pRow->orient), + pRow->doNumber, + pRow->byNumber, + pRow->stepX, + pRow->stepY); + } +} + + +/* ------------------------------------------------------------------ + * Function : "newtrack()". + */ + +static struct track_s *newtrack() +{ + struct track_s *pTrack; + + pTrack = (track_t*)mbkalloc (sizeof (track_t)); + pTrack->next = LV_track; + + return (LV_track = pTrack); +} + + +/* ------------------------------------------------------------------ + * Function : "freetrack()". + */ + +static void freetrack() +{ + struct track_s *pTrack; + + while (LV_track) { + pTrack = LV_track->next; + + mbkfree (LV_track->routingLayers); + mbkfree (LV_track); + + LV_track = pTrack; + } +} + + +/* ------------------------------------------------------------------ + * Function : "ref2TRACK()". + */ + +static void ref2TRACK() +{ + struct phref *pPhref; + struct track_s *pTrack; + + + if (LV_phfig) { + for (pPhref = LV_phfig->PHREF; pPhref != NULL; pPhref = pPhref->NEXT) { + if (!strncmp (pPhref->NAME, "tracks.", 7)) { + pTrack = newtrack (); + + MBK2DEF_track (pPhref, + &pTrack->axisName, + &pTrack->start, + &pTrack->doNumber, + &pTrack->step, + &pTrack->routingLayers, + &pTrack->x, + &pTrack->y); + } + } + } +} + + +/* ------------------------------------------------------------------ + * Function : "buildTRACKS()". + */ + +extern long buildTRACKS(apPhfig, aFlags) + struct phfig *apPhfig; + long aFlags; +{ + long tracksX, tracksY, startX, startY; + char *routingLayers; + + + tracksX = ((apPhfig->XAB2 - apPhfig->XAB1) / MBK_X_GRID) - 1; + tracksY = ((apPhfig->YAB2 - apPhfig->YAB1) / MBK_X_GRID) - 1; + startX = apPhfig->XAB1 + MBK_X_GRID; + startY = apPhfig->YAB1 + MBK_X_GRID; + + routingLayers = routingLayers6; + if (aFlags & F_LAYERS_3) { + routingLayers = routingLayers3; + } + if (aFlags & F_LAYERS_4) { + routingLayers = routingLayers4; + } + + + /* Allocate the horizontal tracks. */ + DEF2MBK_track (apPhfig, + "Y", + MBK2DEF_length (startY), + tracksY, + MBK2DEF_length (MBK_X_GRID), + routingLayers, + apPhfig->XAB1, + apPhfig->YAB1 + MBK_X_GRID); + + + /* Allocate the vertical tracks. */ + DEF2MBK_track (apPhfig, + "X", + MBK2DEF_length (startX), + tracksX, + MBK2DEF_length (MBK_X_GRID), + routingLayers, + apPhfig->XAB1 + MBK_X_GRID, + apPhfig->YAB1); + + + return (TRUE); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintTRACKS()". + */ + +static void fprintTRACKS () +{ + struct track_s *pTrack; + + + for (pTrack = LV_track; pTrack != NULL; pTrack = pTrack->next) { + fprintf (DEF_FILE, + "TRACKS %c %ld DO %ld STEP %ld LAYER %s ;\n", + pTrack->axisName, + pTrack->start, + pTrack->doNumber, + pTrack->step, + pTrack->routingLayers); + } + + + fprintf (DEF_FILE, "\n\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "newblockage()". + */ + +static struct blockage_s *newblockage() +{ + struct blockage_s *pBlockage; + + pBlockage = (blockage_t*)mbkalloc (sizeof (blockage_t)); + pBlockage->next = LV_blockage; + + return (LV_blockage = pBlockage); +} + + +/* ------------------------------------------------------------------ + * Function : "freeblockage()". + */ + +static void freeblockage() +{ + struct blockage_s *pBlockage; + + while (LV_blockage) { + pBlockage = LV_blockage->next; + + mbkfree (LV_blockage); + + LV_blockage = pBlockage; + } +} + + +/* ------------------------------------------------------------------ + * Function : "ref2BLOCKAGE()". + */ + +static void ref2BLOCKAGE() +{ + struct phref *pPhref; + struct blockage_s *pBlockage; + + + if (LV_phfig) { + for (pPhref = LV_phfig->PHREF; pPhref != NULL; pPhref = pPhref->NEXT) { + if (!strncmp (pPhref->NAME, "blockage.", 9)) { + pBlockage = newblockage (); + + MBK2DEF_blockage (pPhref, + &pBlockage->x, + &pBlockage->y, + &pBlockage->width, + &pBlockage->height); + } + } + } +} + + +/* ------------------------------------------------------------------ + * Function : "fprintBLOCKAGE()". + */ + +static void fprintBLOCKAGE() +{ + struct blockage_s *pBlockage; + long layer; + + + for (pBlockage = LV_blockage; + pBlockage != NULL; pBlockage = pBlockage->next) { + + if (pBlockage == LV_blockage) { + fprintf (DEF_FILE, " - _BLOCKAGE_RESERVED"); + fprintf (DEF_FILE, "\n + ROUTED "); + } else { + fprintf (DEF_FILE, "\n NEW "); + } + + for (layer = 1; layer < 7; layer++) { + if (layer != 1) + fprintf (DEF_FILE, "\n NEW "); + + fprintf (DEF_FILE, + "L_ALU%ld %ld + SHAPE BLOCKAGEWIRE ( %ld %ld ) ( %ld * )", + layer, + pBlockage->height, + pBlockage->x, + pBlockage->y + pBlockage->height / 2, + pBlockage->x + pBlockage->width); + } + } + + if (LV_blockage) + fprintf (DEF_FILE, "\n + SOURCE DIST + USE GROUND + WEIGHT 0 ;\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintVIAMATRIX()". + */ + +static void fprintVIAMATRIX (aType, aWidth, aHeight) + char aType; + long aWidth; + long aHeight; +{ + long xCutNB, yCutNB, xCut, yCut; + + + xCutNB = (aWidth / MBKSCALE(5)) / 2; + yCutNB = (aHeight / MBKSCALE(5)) / 2; + + + for (xCut = - xCutNB; xCut <= xCutNB; xCut++) { + for (yCut = - yCutNB; yCut <= yCutNB; yCut++) { + fprintf (DEF_FILE, " + RECT %s ( %ld %ld ) ( %ld %ld )\n", + DEF_layer2a (aType), + MBK2DEF_length (xCut - SCALE_X / 2), + MBK2DEF_length (yCut - SCALE_X / 2), + MBK2DEF_length (xCut + SCALE_X / 2), + MBK2DEF_length (yCut + SCALE_X / 2)); + } + } +} + + +/* ------------------------------------------------------------------ + * Function : "fprintVIAS()". + */ + +static void fprintVIAS() +{ + struct tLoseg_s *pTLoseg; + struct eMVIA_s *pMVIA; + long nVIA, flagDefault, width, height; + char viaName[1024]; + + + pTLoseg = gettloseg (LV_phfig); + + if (pTLoseg) { + nVIA = 0; + + __DBG( + fflush (stdout); + fprintf (stderr, "pTLoseg := 0x%08lx\n", (unsigned long)pTLoseg); + fprintf (stderr, "tMVIA := 0x%08lx\n", (unsigned long)pTLoseg->tMVIA); + fflush (stderr); + ) + + for (pMVIA = pTLoseg->tMVIA; pMVIA != NULL; pMVIA = pMVIA->next) + { nVIA++; } + + fprintf (DEF_FILE, "VIAS %ld ;\n", nVIA); + + for (pMVIA = pTLoseg->tMVIA; pMVIA != NULL; pMVIA = pMVIA->next) { + flagDefault = (pMVIA->width <= MBKSCALE(2)) + && (pMVIA->height <= MBKSCALE(2)); + + __DBG( + if (!flagDefault) { + fprintf (stderr, "macro VIA : %d (%ldx%ld)\n", + (int)pMVIA->type, pMVIA->width, pMVIA->height); + } + ) + + width = MBKSCALE(2); + height = MBKSCALE(2); + + fprintf (DEF_FILE, " - %s", DEF_via2a (pMVIA->type, + pMVIA->width, + pMVIA->height, viaName)); + + if (!flagDefault) { + width = pMVIA->width; + height = pMVIA->height; + } + + fprintf (DEF_FILE, "\n + RECT %s ( %ld %ld ) ( %ld %ld )\n", + DEF_layer2a (getBottomVIALayer (pMVIA->type)), + DEF2MBK_length (- width / 2), + DEF2MBK_length (- height / 2), + DEF2MBK_length ( width / 2), + DEF2MBK_length ( height / 2)); + + fprintVIAMATRIX (pMVIA->type, width, height); + + fprintf (DEF_FILE, " + RECT %s ( %ld %ld ) ( %ld %ld ) ;\n", + DEF_layer2a (getTopVIALayer (pMVIA->type)), + DEF2MBK_length (- width / 2), + DEF2MBK_length (- height / 2), + DEF2MBK_length ( width / 2), + DEF2MBK_length ( height / 2)); + } + + fprintf (DEF_FILE, "END VIAS\n\n"); + } +} + + +/* ------------------------------------------------------------------ + * Function : "fprintPIN()". + */ + +static void fprintPIN(apLocon, apPhcon, asState) + struct locon *apLocon; + struct phcon *apPhcon; + char *asState; +{ + char sSig[1024]; + long conLength; + + + MBK2DEF_name(sSig, apLocon->NAME); + + + fprintf(DEF_FILE, " - %s.%ld + NET %s", sSig, apPhcon->INDEX, sSig); + + if (isvdd(apLocon->NAME)) { + /* + * if (LV_Flags & F_FIXED_PINS) + * fprintf(DEF_FILE, " + SPECIAL"); + */ + + fprintf(DEF_FILE, " + DIRECTION INPUT + USE POWER"); + } else if (isvss(apLocon->NAME)) { + /* + * if (LV_Flags & F_FIXED_PINS) + * fprintf(DEF_FILE, " + SPECIAL"); + */ + + fprintf(DEF_FILE, " + DIRECTION INPUT + USE GROUND"); + } else + fprintf(DEF_FILE, " + DIRECTION %s", + DIRtoa(MBK2DEF_locondir(apLocon))); + + if ( (LV_Flags & F_FIXED_PINS) + && (strncmp(apLocon->NAME, "vddv", 4)) + && (strncmp(apLocon->NAME, "vssv", 4)) + && !isvdd (apLocon->NAME) + && !isvss (apLocon->NAME)) { + conLength = MBK_X_GRID; + if (LV_Flags & F_EXPAND_ROUTE) conLength += FLOOR_XY_EXPAND; + + if (strcmp ("UNPLACED", asState)) { + fprintf(DEF_FILE, "\n + %s ( %ld %ld ) %s", + asState, + apPhcon->XCON, + apPhcon->YCON, + DEF_side2a (apPhcon->ORIENT)); + + if (LV_Flags & F_EXPAND_PLACE) conLength += FLOOR_XY_EXPAND; + } else { + if (LV_Flags & F_EXPAND_PLACE) conLength += FLOOR_XY_EXPAND / 2; + } + + fprintf(DEF_FILE, " + LAYER %s ( %ld 0 ) ( %ld %ld )", + DEF_layer2a (apPhcon->LAYER), + - MBK2DEF_length (apPhcon->WIDTH / 2), + MBK2DEF_length (apPhcon->WIDTH / 2), + MBK2DEF_length (conLength)); + } + + fprintf(DEF_FILE, " ;\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintPINS()". + */ + +static void fprintPINS() +{ + struct locon *pLoCon; + struct phcon Phcon; + struct eLoseg_s *pLoseg; + long loconNB, phconNB; + + + loconNB = 0; + + /* First : compute the number of terminals. */ + for(pLoCon = LV_lofig->LOCON; + pLoCon != (locon_list*)NULL; pLoCon = pLoCon->NEXT) { + loconNB += 1; + phconNB = 0; + + if (LV_phfig) { + pLoseg = getloseglist (LV_phfig, getsigname (pLoCon->SIG)); + + for (; pLoseg != NULL; pLoseg = pLoseg->next) { + if (pLoseg->type == LOSEG_CON) { phconNB += 1; } + } + + if (phconNB > 1) loconNB += phconNB - 1; + } + } + + fprintf(DEF_FILE, "\n\nPINS %ld ;\n", loconNB); + + for(pLoCon = LV_lofig->LOCON; + pLoCon != (locon_list*)NULL; pLoCon = pLoCon->NEXT) { + + phconNB = 0; + + if (LV_phfig) { + pLoseg = getloseglist (LV_phfig, getsigname (pLoCon->SIG)); + + for (; pLoseg != NULL; pLoseg = pLoseg->next) { + __DBG( + fprintf (stderr, "sig %s pLoseg->type := %ld\n", + getsigname (pLoCon->SIG), + pLoseg->type); + fflush (stderr); + ) + if (pLoseg->type == LOSEG_CON) { + phconNB += 1; + + fprintPIN (pLoCon, (struct phcon*)(pLoseg->MBKobj), "FIXED"); + } + } + } + + if (!phconNB) { + Phcon.XCON = 0; + Phcon.YCON = 0; + Phcon.INDEX = 0; + Phcon.WIDTH = MBKSCALE(2); + Phcon.LAYER = ALU2; + Phcon.ORIENT = SOUTH; + + fprintPIN (pLoCon, &Phcon, "UNPLACED"); + } + } + + fprintf(DEF_FILE, "END PINS\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "checkPhins()". + */ + +static long checkPhins(apPhins) + struct phins *apPhins; +{ + struct row_s *pRow; + char sameOrient, oppositeOrient, orient; + + + orientPhfig (getphfig (apPhins->FIGNAME, 'A'), + &sameOrient, + &oppositeOrient); + + orient = DEF_N; + + switch (normOrient (MBK2DEF_transf (apPhins->TRANSF))) { + case DEF_W: + case DEF_N: orient = sameOrient; break; + case DEF_FE: + case DEF_FS: orient = oppositeOrient; break; + } + + pRow = getBaseRow (apPhins->XINS, apPhins->YINS, orient); + + + if (!pRow) { + warnMBK (NULL); + wprintf ("\n Instance %s of model %s at (%ld,%ld) is NOT on row grid.\n", + apPhins->INSNAME, + apPhins->FIGNAME, + apPhins->XINS, + apPhins->YINS); + wprintf ( " Will be removed from the placement file.\n"); + + return (FALSE); + } + + return (TRUE); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintCOMPONENTS()". + */ + +static void fprintCOMPONENTS() +{ + loins_list *pLoins; + phins_list *pPhins; + long loInsNB; + + + /* First : compute the number of instances. */ + for(pLoins = LV_lofig->LOINS, loInsNB = 0L; + pLoins != NULL; loInsNB++, pLoins = pLoins->NEXT); + + fprintf(DEF_FILE, "\n\nCOMPONENTS %ld ;\n", loInsNB); + + /* Dump the list of instance/model pairs. */ + for(pLoins = LV_lofig->LOINS; + pLoins != (loins_list*)NULL; pLoins = pLoins->NEXT) { + fprintf(DEF_FILE, " - %s %s ", pLoins->INSNAME, pLoins->FIGNAME); + + if (!(pPhins = getphinslink(pLoins)) || !checkPhins (pPhins)) { + fprintf(DEF_FILE, ";\n"); + } else { + fprintf(DEF_FILE, + "+ FIXED ( %ld %ld ) %s ;\n", + MBK2DEF_length(pPhins->XINS), + MBK2DEF_length(pPhins->YINS), + DEF_orient2a(MBK2DEF_transf (pPhins->TRANSF))); + } + } + + + fprintf(DEF_FILE, "END COMPONENTS\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintWIRESEG()". + */ + +static void fprintWIRESEG(apPhseg, aFlags) + struct phseg *apPhseg; + long aFlags; +{ + fprintf (DEF_FILE, "%s ", DEF_layer2a (apPhseg->LAYER)); + + if (aFlags & F_SEG_WIDTH) + fprintf (DEF_FILE, "%ld ", MBK2DEF_length (apPhseg->WIDTH)); + + if (aFlags & F_SEG_STRIPE) + fprintf (DEF_FILE, "+ SHAPE STRIPE "); + + fprintf (DEF_FILE, "( %ld %ld ) ( %ld %ld ) ", + MBK2DEF_length (apPhseg->X1), + MBK2DEF_length (apPhseg->Y1), + MBK2DEF_length (apPhseg->X2), + MBK2DEF_length (apPhseg->Y2)); + + __DBG( + fprintf (stderr, "MBK X1 := %ld, DEF X1 := %ld\n", + apPhseg->X1, MBK2DEF_length (apPhseg->X1)); + ) +} + + +/* ------------------------------------------------------------------ + * Function : "fprintWIREVIA()". + */ + +static void fprintWIREVIA(apPhvia, aFlags) + struct phvia *apPhvia; + long aFlags; +{ + char viaName[1024]; + + + fprintf (DEF_FILE, "%s ", DEF_layer2a (getBottomVIALayer (apPhvia->TYPE))); + + if (aFlags & F_SEG_WIDTH) + fprintf (DEF_FILE, "%ld ", MBK2DEF_length (apPhvia->DX)); + + fprintf (DEF_FILE, "( %ld %ld ) %s ", + MBK2DEF_length (apPhvia->XVIA), + MBK2DEF_length (apPhvia->YVIA), + DEF_via2a (apPhvia->TYPE, apPhvia->DX, apPhvia->DY, viaName)); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintWIRES()". + */ + +static void fprintWIRES(apLosig) + struct losig *apLosig; +{ + struct eLoseg_s *pLoseg; + long flagFirst, flagSeg; + + + flagFirst = TRUE; + pLoseg = getloseglist (LV_phfig, getsigname (apLosig)); + + flagSeg = 0L; + if (LV_localFlags & F_SPECIAL_NET) { + flagSeg = F_SEG_STRIPE | F_SEG_WIDTH; + } + + + if (pLoseg) { + for (; pLoseg != NULL; pLoseg = pLoseg->next) { + if (!flagFirst) + fprintf (DEF_FILE, "\n NEW "); + + switch (pLoseg->type) { + case LOSEG_SEG: + if (flagFirst) fprintf (DEF_FILE, "\n + ROUTED "); + fprintWIRESEG ((struct phseg*)pLoseg->MBKobj, flagSeg); + flagFirst = FALSE; + break; + case LOSEG_VIA: + if (flagFirst) fprintf (DEF_FILE, "\n + ROUTED "); + fprintWIREVIA ((struct phvia*)pLoseg->MBKobj, flagSeg); + flagFirst = FALSE; + break; + } + + } + } +} + + +/* ------------------------------------------------------------------ + * Function : "fprintNET()". + */ + +static void fprintNET(apLoSig, aUse) + losig_list *apLoSig; + char aUse; +{ + struct ptype *pType; + struct chain *pChain; + struct locon *pLoCon; + struct authelem *pElem; + char sLine[80], sItem[1024]; + char *sSig, sSigLEF[1024], sConLEF[1024]; + long lLine; + + + /* Try to guess if this is a VST devectorized internal signal. + * We first seach a loseg with the signal name, if nothing is + * found we try with a vectorized name. + */ + sSig = getsigname (apLoSig); + pElem = searchauthelem (LV_htTerm, sSig); + + /* In case of external signal, override with the terminal name. */ + if (pElem != NULL) { sSig = (char*)pElem->VALUE; } + + pType = getptype(apLoSig->USER, (long)LOFIGCHAIN); + if (pType == (ptype_list*)NULL) { + wprinth((char*)NULL); + wprintf(" Signal \"%s\" have no LOFIGCHAIN.\n", sSig); + + pChain = (chain_list*)NULL; + } else { + pChain = (chain_list*)(pType->DATA); + } + + + sSig = MBK2DEF_name(sSigLEF, sSig); +/*snprintf(sItem, 79, " - %s ", sSig);*/ + sprintf(sItem, " - %s ", sSig); + + sLine[0] = (char)0; lLine = 0L; + if (strlen (sItem) > 79) + fprintf(DEF_FILE, "%s\n", sItem); + else + strLCat(sLine, sItem, &lLine, 79); + + + + for(; pChain != (chain_list*)NULL; + pChain = pChain->NEXT) { + pLoCon = (locon_list*)(pChain->DATA); + + if (pLoCon->TYPE == INTERNAL) { + /*snprintf(sItem, 79, "( %s %s ) ", + * ((loins_list*)(pLoCon->ROOT))->INSNAME, + * MBK2DEF_name(sConLEF, pLoCon->NAME)); + */ + sprintf(sItem, "( %s %s ) ", + ((loins_list*)(pLoCon->ROOT))->INSNAME, + MBK2DEF_name(sConLEF, pLoCon->NAME)); + + if (lLine + strlen(sItem) + 4 > 70) { + fprintf(DEF_FILE, "%s", sLine); + if (strlen (sItem) > 70) { + /* sItem too long anyway... flush it immediatly. */ + fprintf(DEF_FILE, " %s\n", sItem); + sItem[0] = (char)0; + } else { + fprintf(DEF_FILE, "\n"); + } + lLine = 0L; + strLCat(sLine, " ", &lLine, 79); + } + strLCat(sLine, sItem, &lLine, 79); + } + } + if (lLine > 0) fprintf(DEF_FILE, "%s", sLine); + + if (LV_phfig) fprintWIRES (apLoSig); + + if (aUse != C_USE_NONE) + fprintf(DEF_FILE, "\n + USE %s ;\n", USEtoa(aUse)); + else + fprintf(DEF_FILE, ";\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintNETS()". + */ + +static void fprintNETS() +{ + losig_list *pLoSig; + long loSigNB; + char *sSig; + + + LV_localFlags &= ~ F_SPECIAL_NET; + LV_localFlags |= F_REGULAR_NET; + + + /* First : compute the number of signals. */ + for(pLoSig = LV_lofig->LOSIG, loSigNB = 0L; + pLoSig != (losig_list*)NULL; pLoSig = pLoSig->NEXT) { + sSig = getsigname(pLoSig); + if (isvdd(sSig) || isvss(sSig)) continue; + + loSigNB += 1; + } + + fprintf(DEF_FILE, "\n\nNETS %ld ;\n", loSigNB); + + /* Dump the list of signal connections. */ + for(pLoSig = LV_lofig->LOSIG; + pLoSig != (losig_list*)NULL; pLoSig = pLoSig->NEXT) { + + sSig = getsigname(pLoSig); + if ( isvdd(sSig) + || isvss(sSig) + || !strcmp(sSig, "cki")) continue; + + fprintNET(pLoSig, C_USE_NONE); + } + + fprintf(DEF_FILE, "END NETS\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintSPECIALNETS()". + */ + +static void fprintSPECIALNETS() +{ + losig_list *pLoSig; + long loSigNB; + char *sSig, Use; + + + LV_localFlags &= ~ F_REGULAR_NET; + LV_localFlags |= F_SPECIAL_NET; + + + /* First : compute the number of signals. */ + for(pLoSig = LV_lofig->LOSIG, loSigNB = 0L; + pLoSig != (losig_list*)NULL; pLoSig = pLoSig->NEXT) { + sSig = getsigname(pLoSig); + if ( !isvdd(sSig) + && !isvss(sSig) + && strcmp(sSig, "cki")) continue; + + loSigNB += 1; + } + + fprintf(DEF_FILE, "\n\nSPECIALNETS %ld ;\n", + loSigNB + ((LV_blockage) ? 1 : 0)); + + /* Dump the list of signal connections. */ + for(pLoSig = LV_lofig->LOSIG; + pLoSig != (losig_list*)NULL; pLoSig = pLoSig->NEXT) { + + sSig = getsigname(pLoSig); + + Use = C_USE_NONE; + if ( isvdd(sSig) ) Use = C_USE_POWER; + if ( isvss(sSig) ) Use = C_USE_GROUND; + if (!strcmp(sSig, "cki")) Use = C_USE_CLOCK; + if (Use == C_USE_NONE) continue; + + fprintNET(pLoSig, Use); + } + + fprintBLOCKAGE (); + + fprintf(DEF_FILE, "END SPECIALNETS\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintDEF()". + */ + +static void fprintDEF() +{ + fprintf (DEF_FILE, "DESIGN %s ;\n\n\n" , LV_name); + fprintf (DEF_FILE, " TECHNOLOGY %s ;\n\n" , "cmos_12"); + fprintf (DEF_FILE, " UNITS DISTANCE MICRONS %ld ;\n", DEF_UNITS_MICRONS); + + if (LV_phfig) { + fprintDIEAREA (); + + ref2ROW (); + if (!LV_row) { + wprinth ("fprintfDEF"); + wprintf ("\n Generate default rows and tracks. This may lead to"); + wprintf ("\n incorrect results if the design is expanded.\n"); + + buildROWS (LV_phfig); + buildTRACKS (LV_phfig, LV_Flags); + } else { + ref2TRACK (); + } + + fprintROWS (); + fprintTRACKS (); + + ref2BLOCKAGE(); + + fprintVIAS (); + } + + + fprintCOMPONENTS (); + fprintPINS (); + fprintNETS (); + + fprintSPECIALNETS (); + + fprintf(DEF_FILE, "\n\nEND DESIGN\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "defsavelophfig()". +*/ + +extern void defsavelophfig(apLofig, apPhfig, aDefName, aFlags) + struct lofig *apLofig; + struct phfig *apPhfig; + char *aDefName; + long aFlags; +{ + LV_Flags = aFlags; + LV_lofig = apLofig; + LV_phfig = apPhfig; + LV_name = aDefName; + LV_row = NULL; + LV_track = NULL; + LV_blockage = NULL; + + if (LV_phfig) { + addfeed (LV_lofig, LV_phfig); + lofigchain (LV_lofig); + } + + buildphinslinks (); + buildtterm (); + + if (!LV_name) LV_name = apLofig->NAME; + DEF_FILE = mbkfopen (LV_name, "def", "w+"); + + fprintDEF (); + if (LV_phfig) checklosegaccess (LV_phfig); + + fclose (DEF_FILE); + freerow (); + freetrack (); + freeblockage (); + + freetterm (); + freephinslinks (); + + if (LV_phfig) { + delfeed (LV_lofig); + lofigchain (LV_lofig); + } +} diff --git a/alliance/src/sea/src/DEF_drive.h b/alliance/src/sea/src/DEF_drive.h new file mode 100644 index 00000000..8a659d1c --- /dev/null +++ b/alliance/src/sea/src/DEF_drive.h @@ -0,0 +1,43 @@ +/* + * $Id: DEF_drive.h,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Header : "./DEF_drive.h" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# ifndef __DEF_drive__ +# define __DEF_drive__ + + +# define F_PHFIG 0x00000001 +# define F_FIXED_PINS 0x00000002 +# define F_PAD 0x00000004 +# define F_LAYERS_3 0x00000008 +# define F_LAYERS_4 0x00000010 +# define F_LAYERS_6 0x00000020 +# define F_EXPAND_PLACE 0x00000040 +# define F_EXPAND_ROUTE 0x00000080 +# define F_TRUST_ORIENT 0x00000100 + + + extern long hasROW (struct phfig *apPhfig); + extern long buildROWS (struct phfig *apPhfig); + extern long buildTRACKS (struct phfig *apPhfig, long aFlags); + extern void defsavelophfig (struct lofig *apLofig, + struct phfig *apPhfig, + char *aDefName, + long aFlags); + +# endif diff --git a/alliance/src/sea/src/DEF_grammar.h b/alliance/src/sea/src/DEF_grammar.h new file mode 100644 index 00000000..e77abbc2 --- /dev/null +++ b/alliance/src/sea/src/DEF_grammar.h @@ -0,0 +1,37 @@ +/* + * $Id: DEF_grammar.h,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Mael Nagat | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Header : "./DEF_grammar.h" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + +# ifndef __DEF_grammar__ +# define __DEF_grammar__ + +# define F_DEF_SPLIT_POWER 0x00000001 +# define F_DEF_NO_IOS 0x00000002 +# define F_DEF_NO_INTERF 0x00000004 +# define F_DEF_MERGE_TERM 0x00000008 +# define F_DEF_SHRINK 0x00000010 + + + extern void defloadlophfig (lofig_list *apLoFig, + phfig_list *apPhFig, + char *aName, + char aMode, + long aVL, + long aFlags); + + +# endif diff --git a/alliance/src/sea/src/DEF_grammar_lex.l b/alliance/src/sea/src/DEF_grammar_lex.l new file mode 100644 index 00000000..0516b047 --- /dev/null +++ b/alliance/src/sea/src/DEF_grammar_lex.l @@ -0,0 +1,268 @@ +%{ +/* + * $Author: jpc $ + * $Id: DEF_grammar_lex.l,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * $Date: 2002/04/25 16:16:20 $ + */ + +#include +#include +#include +#include +#include "util_Defs.h" +#include "DEF_grammar_yacc.h" + + +# define YY_NO_UNPUT +# define yylval DEF_grammarlval +# define yylineno DEF_grammarlineno + + + int yylineno = 1; + + +static int yywrap(void); +static int string(void); +static int history(void); + +%} + + +L [_A-Za-z] +D [0-9] +S [\-\+] +E [eE] +X [\.\-\<\>\[\]\(\)] + +%% + +[ \t\f] { } + +\n { ++yylineno; } +#.* { } + +"VERSION" { return T_VERSION; } +"NAMESCASESENSITIVE" { return T_NAMESCASESENSITIVE; } +"NAMEMAPSTRING" { return T_NAMEMAPSTRING; } +"HISTORY" { history (); } +"DESIGN" { return T_DESIGN; } +"VIAS" { return T_VIAS; } +"TECHNOLOGY" { return T_TECH; } +"UNITS" { return T_UNITS; } +"BUSBITCHARS" { return T_BUSBITCHARS; } +"DIVIDERCHAR" { return T_DIVIDERCHAR; } +"DISTANCE" { return T_DISTANCE; } +"MICRONS" { return T_MICRONS; } +"RECT" { return T_RECT; } +"REENTRANTPATHS" { return T_REENTRANTPATHS; } +"SITE" { return T_SITE; } +"CANPLACE" { return T_CANPLACE; } +"CANNOTOCCUPY" { return T_CANNOTOCCUPY; } +"DIEAREA" { return T_DIE_AREA; } +"PINS" { return T_PINS; } +"DEFAULTCAP" { return T_DEFAULTCAP; } +"MINPINS" { return T_MINPINS; } +"WIRECAP" { return T_WIRECAP; } +"TRACKS" { return T_TRACKS; } +"GCELLGRID" { return T_GCELLGRID; } +"DO" { return T_DO; } +"BY" { return T_BY; } +"STEP" { return T_STEP; } +"LAYER" { return T_LAYER; } +"COMPONENTS" { return T_COMPS; } +"GENERATE" { return T_COMP_GEN; } +"SOURCE" { return T_SOURCE; } +"WEIGHT" { return T_WEIGHT; } +"FIXED" { return T_FIXED; } +"COVER" { return T_COVER; } +"PLACED" { return T_PLACED; } +"UNPLACED" { return T_UNPLACED; } +"FOREIGN" { return T_FOREIGN; } +"EEQMASTER" { return T_EEQMASTER; } +"REGION" { return T_REGION; } +"REGIONS" { return T_REGIONS; } +"NETS" { return T_NETS; } +"MUSTJOIN" { return T_MUSTJOIN; } +"ORIGINAL" { return T_ORIGINAL; } +"USE" { return T_USE; } +"STYLE" { return T_STYLE; } +"PATTERN" { return T_PATTERN; } +"PATTERNNAME" { return T_PATTERNNAME; } +"NONDEFAULTRULE" { return T_NONDEFAULTRULE; } +"ESTCAP" { return T_ESTCAP; } +"ROUTED" { return T_ROUTED; } +"ROW" { return T_ROW; } +"TAPER" { return T_TAPER; } +"TAPERRULE" { return T_TAPERRULE; } +"NEW" { return T_NEW; } +"SHAPE" { return T_SHAPE; } +"SPECIALNETS" { return T_SNETS; } +"SPECIALNET" { return T_SNET; } +"WIDTH" { return T_WIDTH; } +"VOLTAGE" { return T_VOLTAGE; } +"SPACING" { return T_SPACING; } +"N" { return T_N; } +"S" { return T_S; } +"E" { return T_E; } +"W" { return T_W; } +"FN" { return T_FN; } +"FS" { return T_FS; } +"FE" { return T_FE; } +"FW" { return T_FW; } +"INPUT" { return T_INPUT; } +"OUTPUT" { return T_OUTPUT; } +"INOUT" { return T_INOUT; } +"FEEDTHRU" { return T_FEEDTHRU; } +"GROUPS" { return T_GROUPS; } +"GROUP" { return T_GROUP; } +"COMPONENT" { return T_COMPONENT; } +"SOFT" { return T_SOFT; } +"MAXX" { return T_MAXX; } +"MAXY" { return T_MAXY; } +"MAXHALFPERIMETER" { return T_MAXHALFPERIMETER; } +"CONSTRAINTS" { return T_CONSTRAINTS; } +"NET" { return T_NET; } +"PATH" { return T_PATH; } +"SUM" { return T_SUM; } +"DIFF" { return T_DIFF; } +"RISEMIN" { return T_RISEMIN; } +"RISEMAX" { return T_RISEMAX; } +"FALLMIN" { return T_FALLMIN; } +"FALLMAX" { return T_FALLMAX; } +"WIREDLOGIC" { return T_WIREDLOGIC; } +"MAXDIST" { return T_MAXDIST; } +"ASSERTIONS" { return T_ASSERTIONS; } +"END" { return T_END; } +"ARRAY" { return T_ARRAY; } +"FLOORPLAN" { return T_FLOORPLAN; } +"SCANCHAINS" { return T_SCANCHAINS; } +"START" { return T_START; } +"FLOATING" { return T_FLOATING; } +"ORDERED" { return T_ORDERED; } +"STOP" { return T_STOP; } +"TIMINGDISABLES" { return T_TIMINGDISABLES; } +"IOTIMINGS" { return T_IOTIMINGS; } +"RISE" { return T_RISE; } +"FALL" { return T_FALL; } +"VARIABLE" { return T_VARIABLE; } +"SLEWRATE" { return T_SLEWRATE; } +"CAPACITANCE" { return T_CAPACITANCE; } +"DRIVECELL" { return T_DRIVECELL; } +"FROMPIN" { return T_FROMPIN; } +"TOPIN" { return T_TOPIN; } +"PARALLEL" { return T_PARALLEL; } +"PARTITIONS" { return T_PARTITIONS; } +"TURNOFF" { return T_TURNOFF; } +"FROMCLOCKPIN" { return T_FROMCLOCKPIN; } +"FROMCOMPPIN" { return T_FROMCOMPPIN; } +"FROMIOPIN" { return T_FROMIOPIN; } +"TOCLOCKPIN" { return T_TOCLOCKPIN; } +"TOCOMPPIN" { return T_TOCOMPPIN; } +"TOIOPIN" { return T_TOIOPIN; } +"SETUPRISE" { return T_SETUPRISE; } +"SETUPFALL" { return T_SETUPFALL; } +"HOLDRISE" { return T_HOLDRISE; } +"HOLDFALL" { return T_HOLDFALL; } +"VPIN" { return T_VPIN; } +"SUBNET" { return T_SUBNET; } +"XTALK" { return T_XTALK; } +"PIN" { return T_PIN; } +"SYNTHESIZED" { return T_SYNTHESIZED; } +"SPECIAL" { return T_SPECIAL; } +"DIRECTION" { return T_DIRECTION; } +"RANGE" { return T_RANGE; } +"FLOORPLANCONSTRAINTS" { return T_FPC; } +"HORIZONTAL" { return T_HORIZONTAL; } +"VERTICAL" { return T_VERTICAL; } +"ALIGN" { return T_ALIGN; } +"MIN" { return T_MIN; } +"MAX" { return T_MAX; } +"EQUAL" { return T_EQUAL; } +"BOTTOMLEFT" { return T_BOTTOMLEFT; } +"TOPRIGHT" { return T_TOPRIGHT; } +"ROWS" { return T_ROWS; } +"PROPERTYDEFINITIONS" { return T_PROPERTYDEFINITIONS; } +"PROPERTY" { return T_PROPERTY; } +"REAL" { return T_REAL; } +"INTEGER" { return T_INTEGER; } +"BEGINEXT" { return T_BEGINEXT; } +"PINPROPERTIES" { return T_PINPROPERTIES; } +"COMMONSCANPINS" { return T_COMMONSCANPINS; } +"COMPONENTPIN" { return T_COMPONENTPIN; } +"SHIELD" { return T_SHIELD; } +"SHIELDNET" { return T_SHIELDNET; } +"NOSHIELD" { return T_NOSHIELD; } + +{L}({L}|{D}|{X})* { yylval.s = strdup(yytext); return T_Ident; } +{S}?{D}+ { yylval.n = atof(yytext); return T_Number; } +{S}?{D}+\.{D}* { yylval.n = atof(yytext); return T_Number; } +{S}?{D}*\.{D}+ { yylval.n = atof(yytext); return T_Number; } +{S}?{D}+{E}{S}?{D}+ { yylval.n = atof(yytext); return T_Number; } +{S}?{D}+\.{D}*{E}{S}?{D}+ { yylval.n = atof(yytext); return T_Number; } +{S}?{D}*\.{D}+{E}{S}?{D}+ { yylval.n = atof(yytext); return T_Number; } + +"\"" { return string(); } +. { return *yytext; } + +%% + +static int yywrap() { return (1); } + +static int +string() +{ + char *str; + size_t max; + int c; + size_t len; + + if ((str = (char *)malloc(max = 64)) == NULL) + { perror("string"); exit (1); } + + len = 0; + while ((c = input()) >= 0 && c != '"') { + if (len + 1 == max) + if ((str = (char *)realloc(str, max *= 2)) == NULL) + { perror ("string"); exit (1); } + str[len++] = (char)c; + if (c == '\n') yylineno++; + } + str[len] = '\0'; + if (c == EOF) { + fflush (stdout); + fprintf (stderr, "unterminated string constant"); + exit (1); + } + yylval.s = str; + return T_String; +} + + +static int +history() +{ + char *str; + size_t max; + int c; + size_t len; + + if ((str = (char *)malloc(max = 64)) == NULL) + { perror("history"); exit (1); } + + len = 0; + while ((c = input()) >= 0 && c != ';') { + if (len + 1 == max) + if ((str = (char *)realloc(str, max *= 2)) == NULL) + { perror ("history"); exit (1); } + str[len++] = (char)c; + if (c == '\n') yylineno++; + } + str[len] = '\0'; + if (c == EOF) { + fflush (stdout); + fprintf (stderr, "unterminated history line"); + exit (1); + } + yylval.s = str; + return T_HISTORY; +} diff --git a/alliance/src/sea/src/DEF_grammar_yacc.y b/alliance/src/sea/src/DEF_grammar_yacc.y new file mode 100644 index 00000000..06719014 --- /dev/null +++ b/alliance/src/sea/src/DEF_grammar_yacc.y @@ -0,0 +1,1351 @@ +%{ +/* + * $Author: jpc $ + * $Id: DEF_grammar_yacc.y,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * $Date: 2002/04/25 16:16:20 $ + */ + +#include +#include +#include +#include +#include "util_Defs.h" +#include "DEF_actions.h" + + + /* Flex substitutions. */ +# define yylex DEF_grammarlex +# define yyin DEF_grammarin +# define yylineno DEF_grammarlineno + + +#define YYDEBUG 1 +#define YYERROR_VERBOSE 1 + +extern int yylineno; +extern char *yytext; + +extern void yyerror(char *str); +extern int yylex(void); + +%} + +%union { + double n; + char *s; + struct pt *pt; +}; + +%token T_Number +%token T_Ident +%token T_String +%token T_History + +%type orient +%type direction +%type pt +%type track_start +%type track_layer_statement +%type track_layer +%type track_layers + +%token T_ALIGN T_ARRAY T_ASSERTIONS T_BEGINEXT T_BOTTOMLEFT +%token T_BUSBITCHARS T_BY T_CANNOTOCCUPY T_CANPLACE T_CAPACITANCE +%token T_COMMONSCANPINS T_COMPONENT T_COMPONENTPIN T_COMPS +%token T_COMP_GEN T_CONSTRAINTS T_COVER T_DEFAULTCAP T_DESIGN +%token T_DIE_AREA T_DIFF T_DIRECTION T_DISTANCE T_DIVIDERCHAR T_DO +%token T_DRIVECELL T_E T_EEQMASTER T_END T_EQUAL T_ESTCAP T_FALL +%token T_FALLMAX T_FALLMIN T_FE T_FIXED T_FLOATING T_FLOORPLAN T_FN +%token T_FOREIGN T_FPC T_FROMCLOCKPIN T_FROMCOMPPIN T_FROMIOPIN +%token T_FROMPIN T_FS T_FW T_GCELLGRID T_GROUP T_GROUPS T_HISTORY +%token T_HOLDFALL T_HOLDRISE T_HORIZONTAL T_INTEGER T_IOTIMINGS +%token T_LAYER T_MACRO T_MAX T_MAXDIST T_MAXHALFPERIMETER T_MAXX +%token T_MAXY T_MICRONS T_MIN T_MINPINS T_MUSTJOIN T_N +%token T_NAMEMAPSTRING T_NAMESCASESENSITIVE T_NET T_NETS T_NEW +%token T_NONDEFAULTRULE T_NOSHIELD T_ORDERED T_ORIGINAL T_PARALLEL +%token T_PARTITIONS T_PATH T_PATTERN T_PATTERNNAME T_PIN +%token T_PINPROPERTIES T_PINS T_PLACED T_PROPERTY +%token T_PROPERTYDEFINITIONS T_RANGE T_REAL T_RECT T_REENTRANTPATHS +%token T_REGION T_REGIONS T_RISE T_RISEMAX T_RISEMIN T_ROUTED T_ROW +%token T_ROWS T_S T_SCANCHAINS T_SETUPFALL T_SETUPRISE T_SHAPE +%token T_SHIELD T_SHIELDNET T_SITE T_SLEWRATE T_SNET T_SNETS T_SOFT +%token T_SOURCE T_SPACING T_SPECIAL T_START T_STEP T_STOP T_STYLE +%token T_SUBNET T_SUM T_SYNTHESIZED T_TAPER T_TAPERRULE T_TECH +%token T_THRUPIN T_TIMINGDISABLES T_TOCLOCKPIN T_TOCOMPPIN T_TOIOPIN +%token T_TOPIN T_TOPRIGHT T_TRACKS T_TURNOFF T_UNITS T_UNPLACED T_USE +%token T_VARIABLE T_VERSION T_VERTICAL T_VIAS T_VOLTAGE T_VPIN T_W +%token T_WEIGHT T_WIDTH T_WIRECAP T_WIREDLOGIC T_XTALK +%token T_INPUT T_OUTPUT T_INOUT T_FEEDTHRU + +%% + +def_file + : version_stmt case_sens_stmt rules + | version_stmt case_sens_stmt rules end_design + ; + +version_stmt + : /* empty */ + | T_VERSION T_Number ';' + ; + +case_sens_stmt + : /* empty */ + | T_NAMESCASESENSITIVE T_Ident ';' + ; + +rules + : /* empty */ + | rules rule + | error + ; + +rule + : design_section + | via_section + | extension_section + | comps_section + | nets_section + | snets_section + | groups_section + | scanchains_section + | constraint_section + | assertions_section + | iotiming_section + | regions_section + | floorplan_contraints_section + | timingdisables_section + | partitions_section + | pin_props_section + ; + +design_section + : design_name + | tech_name + | history + | units + | divider_char + | bus_bit_chars + | site + | canplace + | cannotoccupy + | die_area + | pin_cap_rule + | pin_rule + | tracks_rule + | gcellgrid + | array_name + | floorplan_name + | row_rule + | prop_def_section + ; + +design_name + : T_DESIGN T_Ident ';' { def_design_name($2); } + ; + +end_design + : T_END T_DESIGN { def_end_design(); } + ; + +tech_name + : T_TECH T_Ident ';' { def_tech_name($2); } + ; + +array_name + : T_ARRAY T_Ident ';' + ; + +floorplan_name + : T_FLOORPLAN T_Ident ';' + ; + +history + : T_HISTORY T_History ';' + ; + +prop_def_section + : T_PROPERTYDEFINITIONS property_defs T_END T_PROPERTYDEFINITIONS + ; + +property_defs + : /* empty */ + | property_defs property_def + ; + +property_def + : T_DESIGN T_Ident property_type_and_val ';' + | T_NET T_Ident property_type_and_val ';' + | T_SNET T_Ident property_type_and_val ';' + | T_REGION T_Ident property_type_and_val ';' + | T_GROUP T_Ident property_type_and_val ';' + | T_COMPONENT T_Ident property_type_and_val ';' + | T_ROW T_Ident property_type_and_val ';' + | T_PIN T_Ident property_type_and_val ';' + | T_COMPONENTPIN T_Ident property_type_and_val ';' + ; + +property_type_and_val + : T_INTEGER opt_range opt_num_val {} + | T_REAL opt_range opt_num_val {} + | T_Ident {} + | T_Ident T_String {} + | T_NAMEMAPSTRING T_Ident {} + ; + +opt_num_val + : /* empty */ {} + | T_Number {} + ; + +units + : T_UNITS T_DISTANCE T_MICRONS T_Number ';' { def_units ($4); } + ; + +divider_char + : T_DIVIDERCHAR T_String ';' + ; + +bus_bit_chars + : T_BUSBITCHARS T_String ';' + ; + +site + : T_SITE T_Ident T_Number T_Number orient T_DO T_Number T_BY T_Number T_STEP T_Number T_Number ';' + ; + +canplace + : T_CANPLACE T_Ident T_Number T_Number orient T_DO T_Number T_BY T_Number T_STEP T_Number T_Number ';' + ; + +cannotoccupy + : T_CANNOTOCCUPY T_Ident T_Number T_Number orient T_DO T_Number T_BY T_Number T_STEP T_Number T_Number ';' + ; + +orient + : T_N { $$ = DEF_N; } + | T_E { $$ = DEF_E; } + | T_S { $$ = DEF_S; } + | T_W { $$ = DEF_W; } + | T_FN { $$ = DEF_FN; } + | T_FE { $$ = DEF_FE; } + | T_FS { $$ = DEF_FS; } + | T_FW { $$ = DEF_FW; } + ; + +direction + : T_INPUT { $$ = DEF_INPUT; } + | T_OUTPUT { $$ = DEF_OUTPUT; } + | T_INOUT { $$ = DEF_INOUT; } + | T_FEEDTHRU { $$ = DEF_FEEDTHRU; } + ; + +die_area + : T_DIE_AREA pt pt ';' { def_die_area ($2, $3); } + ; + +pin_cap_rule + : start_def_cap pin_caps end_def_cap + ; + +start_def_cap + : T_DEFAULTCAP T_Number + ; + +pin_caps + : /* empty */ + | pin_caps pin_cap + ; + +pin_cap + : T_MINPINS T_Number T_WIRECAP T_Number ';' + ; + +end_def_cap + : T_END T_DEFAULTCAP + ; + +pin_rule + : start_pins pins end_pins + ; + +start_pins + : T_PINS T_Number ';' { def_start_pins($2); } + ; + +pins + : /* empty */ + | pins pin + ; + +pin + : pin_start pin_options ';' { def_pin_options (); } + ; + +pin_start + : '-' T_Ident '+' T_NET T_Ident { def_pin_start($2, $5); } + ; + +pin_options + : /* empty */ + | pin_options pin_option + ; + +pin_option + : '+' T_SPECIAL + | extension_stmt + | '+' T_DIRECTION direction { def_pin_option_direction ($3); } + | '+' T_USE T_Ident + | '+' T_LAYER T_Ident pt pt { def_pin_option_layer ($3, $4, $5); } + | placement_status pt orient { def_pin_option_place ($2, $3); } + ; + +end_pins + : T_END T_PINS { def_end_pins(); } + ; + +row_rule + : T_ROW T_Ident T_Ident T_Number T_Number orient T_DO T_Number T_BY T_Number T_STEP T_Number T_Number row_options ';' + { def_row_rule ($2, $3, $4, $5, $6, $8, $10, $12, $13); } + ; + +row_options + : /* empty */ + | row_options row_option + ; + +row_option + : '+' T_PROPERTY row_prop_list + ; + +row_prop_list + : /* empty */ + | row_prop_list row_prop + ; + +row_prop + : T_Ident property_val {} + ; + +tracks_rule + : track_start T_Number T_DO T_Number T_STEP T_Number track_layer_statement ';' + { def_track_rule ($1, $2, $4, $6, $7); } + ; + +track_start + : T_TRACKS T_Ident { $$ = $2; } + ; + +track_layer_statement + : /* empty */ { $$ = ""; } + | T_LAYER track_layers { $$ = $2; } + ; + +track_layers + : /* empty */ { $$ = ""; } + | track_layer track_layers { $$ = def_track_layers ($1, $2); } + ; + +track_layer + : T_Ident { $$ = $1; } + ; + +gcellgrid + : T_GCELLGRID T_Ident T_Number T_DO T_Number T_STEP T_Number ';' + ; + +extension_section + : T_BEGINEXT + ; + +extension_stmt + : '+' T_BEGINEXT + ; + +via_section + : via via_declarations via_end + ; + +via + : T_VIAS T_Number ';' { def_start_vias ($2); } + ; + +via_declarations + : /* empty */ + | via_declarations via_declaration + ; + +via_declaration + : via_start layer_stmts ';' { def_via_end (); } + ; + +via_start + : '-' T_Ident { def_via_start ($2); } + ; + +layer_stmts + : /* empty */ + | layer_stmts layer_stmt + ; + +layer_stmt + : '+' T_RECT T_Ident pt pt { def_via_stmt_rect ($3, $4, $5); } + | '+' T_PATTERNNAME T_Ident { def_via_stmt_pattern ($3); } + | extension_stmt + ; + +pt + : '(' T_Number T_Number ')' { $$ = def_alloc_pt ( $2 , $3 ); } + | '(' '*' T_Number ')' { $$ = def_alloc_pt (HUGE_VAL, $3 ); } + | '(' T_Number '*' ')' { $$ = def_alloc_pt ( $2 , HUGE_VAL); } + | '(' '*' '*' ')' { $$ = def_alloc_pt (HUGE_VAL, HUGE_VAL); } + ; + +via_end + : T_END T_VIAS { def_end_vias (); } + ; + +regions_section + : regions_start regions_stmts T_END T_REGIONS + ; + +regions_start + : T_REGIONS T_Number ';' + ; + +regions_stmts + : /* empty */ + | regions_stmts regions_stmt + ; + +regions_stmt + : '-' T_Ident rect_list region_options ';' + ; + +rect_list + : pt pt { } + | rect_list pt pt { } + ; + +region_options + : /* empty */ + | region_options region_option + ; + +region_option + : '+' T_PROPERTY region_prop_list + ; + +region_prop_list + : /* empty */ + | region_prop_list region_prop + ; + +region_prop + : T_Ident property_val {} + ; + +comps_section + : start_comps comps_rule end_comps + ; + +start_comps + : T_COMPS T_Number ';' { def_start_comps($2); } + ; + +comps_rule + : /* empty */ + | comps_rule comp + ; + +comp + : comp_start comp_net_list comp_options ';' + ; + +comp_start + : '-' T_Ident T_Ident { def_comp_start($2, $3); } + ; + +comp_net_list + : /* empty */ {} + | comp_net_list '*' { def_comp_net_list("*"); } + | comp_net_list T_Ident { def_comp_net_list($2); } + ; + +comp_options + : /* empty */ + | comp_options comp_option + ; + +comp_option + : comp_generate + | comp_source + | comp_type + | weight + | comp_foreign + | comp_region + | comp_eeq + | comp_property + | comp_extension_stmt + ; + +comp_extension_stmt + : extension_stmt + ; + +comp_eeq + : '+' T_EEQMASTER T_Ident + ; + +comp_generate + : '+' T_COMP_GEN T_Ident opt_pattern + ; + +opt_pattern + : /* empty */ {} + | T_Ident {} + ; + +comp_source + : '+' T_SOURCE T_Ident + ; + +comp_region + : comp_region_start comp_pnt_list + | comp_region_start T_Ident + ; + +comp_pnt_list + : pt pt { } + | comp_pnt_list pt pt { } + ; + +comp_property + : '+' T_PROPERTY comp_prop_list + ; + +comp_prop_list + : /* empty */ + | comp_prop_list comp_prop + ; + +comp_prop + : T_Ident property_val {} + ; + +comp_region_start + : '+' T_REGION + ; + +comp_foreign + : '+' T_FOREIGN T_Ident opt_paren T_Ident + ; + +opt_paren + : pt {} + | T_Number T_Number {} + ; + +comp_type + : placement_status pt orient { def_comp_type ($2, $3); } + ; + +placement_status + : '+' T_FIXED + | '+' T_COVER + | '+' T_PLACED + | '+' T_UNPLACED + ; + +weight + : '+' T_WEIGHT T_Number + ; + +end_comps + : T_END T_COMPS { def_end_comps(); } + ; + +nets_section + : start_nets net_rules end_nets + ; + +start_nets + : T_NETS T_Number ';' { def_start_nets($2); } + ; + +net_rules + : /* empty */ + | net_rules one_net + ; + +one_net + : net_start net_connections net_options ';' + ; + +net_start + : '-' T_Ident { def_net_start($2); } + ; + +net_connections + : /* empty */ + | net_connections net_connection + ; + +net_connection + : '(' net_conn_start net_conn_opt ')' + | T_MUSTJOIN '(' net_conn_start net_conn_opt ')' + ; + +net_conn_start + : T_Ident T_Ident { def_net_conn_start($1, $2); } + | T_PIN T_Ident { def_net_conn_start("PIN", $2); } + ; + +net_conn_opt + : /* empty */ + | extension_stmt + | '+' T_SYNTHESIZED { def_net_conn_opt_synthesized(); } + ; + +net_options + : /* empty */ + | net_options net_option + ; + +net_option + : '+' net_type paths + | '+' T_SOURCE T_Ident + | '+' T_ORIGINAL T_Ident + | '+' T_PATTERN T_Ident + | '+' T_WEIGHT T_Number + | '+' T_XTALK T_Number + | '+' T_ESTCAP T_Number + | '+' T_USE T_Ident + | '+' T_STYLE T_Ident + | '+' T_NONDEFAULTRULE T_Ident + | vpin_stmt + | '+' T_SHIELDNET T_Ident + | '+' T_NOSHIELD paths + | '+' T_SUBNET T_Ident comp_names subnet_options + | '+' T_PROPERTY net_prop_list + | extension_stmt + ; + +net_prop_list + : /* empty */ + | net_prop_list net_prop + ; + +net_prop + : T_Ident property_val {} + ; + +vpin_stmt + : vpin_begin vpin_layer_opt pt pt vpin_options + ; + +vpin_begin + : '+' T_VPIN T_Ident + ; + +vpin_layer_opt + : /* empty */ + | T_LAYER T_Ident + ; + +property_val + : T_Number {} + | T_String {} + ; + +vpin_options + : /* empty */ + | vpin_status pt orient + ; + +vpin_status + : T_PLACED + | T_FIXED + | T_COVER + ; + +net_type + : T_FIXED + | T_COVER + | T_ROUTED + ; + +paths + : path + | paths new_path + ; + +new_path + : T_NEW path + ; + +path + : path_start opt_width opt_shape opt_taper path_pt path_item_list + ; + +path_start + : T_Ident { def_path_start ($1); } + ; + +path_item_list + : /* empty */ + | path_item_list path_item + ; + +path_item + : T_Ident { def_path_item_via ($1); } + | path_pt + ; + +path_pt + : '(' T_Number T_Number ')' { def_path_item_pt (def_alloc_pt ( $2 , $3 )); } + | '(' '*' T_Number ')' { def_path_item_pt (def_alloc_pt (HUGE_VAL, $3 )); } + | '(' T_Number '*' ')' { def_path_item_pt (def_alloc_pt ( $2 , HUGE_VAL)); } + | '(' '*' '*' ')' { def_path_item_pt (def_alloc_pt (HUGE_VAL, HUGE_VAL)); } + | '(' T_Number T_Number T_Number ')' { def_path_item_pt (def_alloc_pt ( $2 , $3 )); } + | '(' '*' T_Number T_Number ')' { def_path_item_pt (def_alloc_pt (HUGE_VAL, $3 )); } + | '(' T_Number '*' T_Number ')' { def_path_item_pt (def_alloc_pt ( $2 , HUGE_VAL)); } + | '(' '*' '*' T_Number ')' { def_path_item_pt (def_alloc_pt (HUGE_VAL, HUGE_VAL)); } + ; + +opt_taper + : /* empty */ + | T_TAPER + | T_TAPERRULE T_Ident + ; + +opt_shape + : /* empty */ + | '+' T_SHAPE T_Ident + ; + +opt_width + : /* empty */ {} + | T_Number { def_opt_width ($1); } + ; + +end_nets + : T_END T_NETS { def_end_nets(); } + ; + +snets_section + : start_snets snet_rules end_snets + ; + +snet_rules + : /* empty */ + | snet_rules snet_rule + ; + +snet_rule + : snet_start snet_connections snet_options ';' + ; + +snet_start + : '-' T_Ident { def_snet_start($2); } + ; + +snet_connections + : /* empty */ + | snet_connections snet_connection + ; + +snet_connection + : '(' snet_conn_start snet_conn_opt ')' + ; + +snet_conn_start + : T_Ident T_Ident { def_snet_conn_start($1, $2); } + | T_PIN T_Ident { def_snet_conn_start("PIN", $2); } + | '*' T_Ident { def_snet_conn_start("PIN", $2); } + ; + +snet_conn_opt + : /* empty */ + | extension_stmt + | '+' T_SYNTHESIZED { def_snet_conn_opt_synthesized(); } + ; + +snet_options + : /* empty */ + | snet_options snet_option + ; + +snet_option + : snet_width + | snet_voltage + | snet_spacing + | snet_other_option + ; + +snet_other_option + : '+' net_type paths + | '+' T_SHIELD T_Ident paths + | '+' T_SOURCE T_Ident + | '+' T_ORIGINAL T_Ident + | '+' T_PATTERN T_Ident + | '+' T_WEIGHT T_Number + | '+' T_ESTCAP T_Number + | '+' T_USE T_Ident + | '+' T_STYLE T_Ident + | '+' T_PROPERTY net_prop_list + | extension_stmt + ; + +snet_width + : '+' T_WIDTH T_Ident T_Number + ; + +snet_voltage + : '+' T_VOLTAGE T_Number + ; + +snet_spacing + : '+' T_SPACING T_Ident T_Number opt_snet_range + ; + +opt_snet_range + : /* nothing */ + | T_RANGE T_Number T_Number + ; + +opt_range + : /* nothing */ + | T_RANGE T_Number T_Number + ; + +start_snets + : T_SNETS T_Number ';' { def_start_snets($2); } + ; + +end_snets + : T_END T_SNETS { def_end_snets(); } + ; + +groups_section + : groups_start group_rules groups_end + ; + +groups_start + : T_GROUPS T_Number ';' + ; + +group_rules + : /* empty */ + | group_rules group_rule + ; + +group_rule + : start_group group_members group_options ';' + ; + +start_group + : '-' T_Ident + ; + +group_members + : /* empty */ + | group_members group_member + ; + +group_member + : T_Ident {} + ; + +group_options + : /* empty */ + | group_options group_option + ; + +group_option + : '+' T_SOFT group_soft_options + | '+' T_PROPERTY group_prop_list + | '+' T_REGION group_region + | extension_stmt + ; + +group_region + : pt pt {} + | T_Ident {} + ; + +group_prop_list + : /* empty */ + | group_prop_list group_prop + ; + +group_prop + : T_Ident property_val {} + ; + +group_soft_options + : /* empty */ + | group_soft_options group_soft_option + ; + +group_soft_option + : T_MAXX T_Number + | T_MAXY T_Number + | T_MAXHALFPERIMETER T_Number + ; + +groups_end + : T_END T_GROUPS + ; + +assertions_section + : assertions_start constraint_rules assertions_end + ; + +constraint_section + : constraints_start constraint_rules constraints_end + ; + +assertions_start + : T_ASSERTIONS T_Number ';' + ; + +constraints_start + : T_CONSTRAINTS T_Number ';' + ; + +constraint_rules + : /* empty */ + | constraint_rules constraint_rule + ; + +constraint_rule + : operand_rule + | wiredlogic_rule + ; + +operand_rule + : '-' operand delay_specs ';' + ; + +operand + : T_NET T_Ident + | T_PATH T_Ident T_Ident T_Ident T_Ident + | T_SUM '(' operand_list ')' + | T_DIFF '(' operand_list ')' + ; + +operand_list + : operand + | operand_list ',' operand + ; + +wiredlogic_rule + : '-' T_WIREDLOGIC T_Ident opt_plus T_MAXDIST T_Number ';' + ; + +opt_plus + : /* empty */ + | '+' + ; + +delay_specs + : /* empty */ + | delay_specs delay_spec + ; + +delay_spec + : '+' T_RISEMIN T_Number + | '+' T_RISEMAX T_Number + | '+' T_FALLMIN T_Number + | '+' T_FALLMAX T_Number + ; + +constraints_end + : T_END T_CONSTRAINTS + ; + +assertions_end + : T_END T_ASSERTIONS + ; + +scanchains_section + : scanchain_start scanchain_rules scanchain_end + ; + +scanchain_start + : T_SCANCHAINS T_Number ';' + ; + +scanchain_rules + : /* empty */ + | scanchain_rules scan_rule + ; + +scan_rule + : start_scan scan_members ';' + ; + +start_scan + : '-' T_Ident + ; + +scan_members + : /* empty */ + | scan_members scan_member + ; + +opt_pin + : /* empty */ {} + | T_Ident {} + ; + +scan_member + : '+' T_START T_Ident opt_pin + | '+' T_FLOATING floating_inst_list + | '+' T_ORDERED ordered_inst_list + | '+' T_STOP T_Ident opt_pin + | '+' T_COMMONSCANPINS opt_common_pins + | extension_stmt + ; + +opt_common_pins + : /* empty */ + | '(' T_Ident T_Ident ')' + | '(' T_Ident T_Ident ')' '(' T_Ident T_Ident ')' + ; + +floating_inst_list + : /* empty */ + | floating_inst_list one_floating_inst + ; + +one_floating_inst + : T_Ident floating_pins {} + ; + +floating_pins + : /* empty */ + | '(' T_Ident T_Ident ')' + | '(' T_Ident T_Ident ')' '(' T_Ident T_Ident ')' + ; + +ordered_inst_list + : /* empty */ + | ordered_inst_list one_ordered_inst + ; + +one_ordered_inst + : T_Ident ordered_pins {} + ; + +ordered_pins + : /* empty */ + | '(' T_Ident T_Ident ')' + | '(' T_Ident T_Ident ')' '(' T_Ident T_Ident ')' + ; + +scanchain_end + : T_END T_SCANCHAINS + ; + +iotiming_section + : iotiming_start iotiming_rules iotiming_end + ; + +iotiming_start + : T_IOTIMINGS T_Number ';' + ; + +iotiming_rules + : /* empty */ + | iotiming_rules iotiming_rule + ; + +iotiming_rule + : start_iotiming iotiming_members ';' + ; + +start_iotiming + : '-' '(' T_Ident T_Ident ')' + ; + +iotiming_members + : /* empty */ + | iotiming_members iotiming_member + ; + +iotiming_member + : '+' risefall T_VARIABLE T_Number T_Number + | '+' risefall T_SLEWRATE T_Number T_Number + | '+' T_CAPACITANCE T_Number + | '+' T_DRIVECELL T_Ident + | T_FROMPIN T_Ident + | T_TOPIN T_Ident + | T_PARALLEL T_Number + | extension_stmt + ; + +risefall + : T_RISE + | T_FALL + ; + +iotiming_end + : T_END T_IOTIMINGS + ; + +floorplan_contraints_section + : fp_start fp_stmts T_END T_FPC + ; + +fp_start + : T_FPC T_Number ';' + ; + +fp_stmts + : /* empty */ + | fp_stmts fp_stmt + ; + +fp_stmt + : '-' T_Ident h_or_v constraint_type constrain_what_list ';' + ; + +h_or_v + : T_HORIZONTAL + | T_VERTICAL + ; + +constraint_type + : T_ALIGN + | T_MAX T_Number + | T_MIN T_Number + | T_EQUAL T_Number + ; + +constrain_what_list + : /* empty */ + | constrain_what_list constrain_what + ; + +constrain_what + : '+' T_BOTTOMLEFT row_or_comp_list + | '+' T_TOPRIGHT row_or_comp_list + ; + +row_or_comp_list + : /* empty */ + | row_or_comp_list row_or_comp + ; + +row_or_comp + : '(' T_ROWS T_Ident ')' + | '(' T_COMPS T_Ident ')' + ; + +timingdisables_section + : timingdisables_start timingdisables_rules timingdisables_end + ; + +timingdisables_start + : T_TIMINGDISABLES T_Number ';' + ; + +timingdisables_rules + : /* empty */ + | timingdisables_rules timingdisables_rule + ; + +timingdisables_rule + : '-' T_FROMPIN T_Ident T_Ident T_TOPIN T_Ident T_Ident ';' + | '-' T_THRUPIN T_Ident T_Ident ';' + | '-' T_MACRO T_Ident td_macro_option ';' + | '-' T_REENTRANTPATHS ';' + ; + +td_macro_option + : T_FROMPIN T_Ident T_TOPIN T_Ident + | T_THRUPIN T_Ident + ; + +timingdisables_end + : T_END T_TIMINGDISABLES + ; + +partitions_section + : partitions_start partition_rules partitions_end + ; + +partitions_start + : T_PARTITIONS T_Number ';' + ; + +partition_rules + : /* empty */ + | partition_rules partition_rule + ; + +partition_rule + : start_partition partition_members ';' + ; + +start_partition + : '-' T_Ident turnoff + ; + +turnoff + : /* empty */ + | T_TURNOFF turnoff_setup turnoff_hold + ; + +turnoff_setup + : /* empty */ + | T_SETUPRISE + | T_SETUPFALL + ; + +turnoff_hold + : /* empty */ + | T_HOLDRISE + | T_HOLDFALL + ; + +partition_members + : /* empty */ + | partition_members partition_member + ; + +partition_member + : '+' T_FROMCLOCKPIN T_Ident T_Ident risefall minmaxpins + | '+' T_FROMCOMPPIN T_Ident T_Ident risefallminmax2_list + | '+' T_FROMIOPIN T_Ident risefallminmax1_list + | '+' T_TOCLOCKPIN T_Ident T_Ident risefall minmaxpins + | '+' T_TOCOMPPIN T_Ident T_Ident risefallminmax2_list + | '+' T_TOIOPIN T_Ident risefallminmax1_list + | extension_stmt + ; + +minmaxpins + : min_or_max_list T_PINS pin_list + ; + +min_or_max_list + : /* empty */ + | min_or_max_list min_or_max_member + ; + +min_or_max_member + : T_MIN T_Number T_Number + | T_MAX T_Number T_Number + ; + +pin_list + : /* empty */ + | pin_list T_Ident + ; + +risefallminmax1_list + : /* empty */ + | risefallminmax1_list risefallminmax1 + ; + +risefallminmax1 + : T_RISEMIN T_Number + | T_FALLMIN T_Number + | T_RISEMAX T_Number + | T_FALLMAX T_Number + ; + +risefallminmax2_list + : risefallminmax2 + | risefallminmax2_list risefallminmax2 + ; + +risefallminmax2 + : T_RISEMIN T_Number T_Number + | T_FALLMIN T_Number T_Number + | T_RISEMAX T_Number T_Number + | T_FALLMAX T_Number T_Number + ; + +partitions_end + : T_END T_PARTITIONS + ; + +comp_names + : /* empty */ + | comp_names comp_name + ; + +comp_name + : '(' T_Ident T_Ident subnet_opt_syn ')' + ; + +subnet_opt_syn + : /* empty */ + | '+' T_SYNTHESIZED + ; + +subnet_options + : /* empty */ + | subnet_options subnet_option + ; + +subnet_option + : net_type paths + | T_NONDEFAULTRULE T_Ident + ; + +pin_props_section + : begin_pin_props pin_prop_list end_pin_props + ; + +begin_pin_props + : T_PINPROPERTIES T_Number opt_semi + ; + +opt_semi + : /* empty */ + | ';' + ; + +end_pin_props + : T_END T_PINPROPERTIES + ; + +pin_prop_list + : /* empty */ + | pin_prop_list pin_prop_terminal + ; + +pin_prop_terminal + : '-' T_Ident T_Ident pin_prop_options ';' + ; + +pin_prop_options + : /* empty */ + | pin_prop_options pin_prop + ; + +pin_prop + : '+' T_PROPERTY pin_prop_name_value_list + ; + +pin_prop_name_value_list + : /* empty */ + | pin_prop_name_value_list pin_prop_name_value + ; + +pin_prop_name_value + : T_Ident property_val {} + ; + +%% + +void +yyerror(char *str) +{ + def_parse_error(str); +} + diff --git a/alliance/src/sea/src/GNU_Defs.h b/alliance/src/sea/src/GNU_Defs.h new file mode 100644 index 00000000..f95b2c4a --- /dev/null +++ b/alliance/src/sea/src/GNU_Defs.h @@ -0,0 +1,100 @@ + +/* + * $Id: GNU_Defs.h,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Header : "./GNU_Defs.h" | + * | ************************************************************** | + * | | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# ifdef __GNUC__ +# if defined(__sparc__) && !defined(__svr4__) +# define __MISS_GNU_PROTO__ 1 +# else +# define __MISS_GNU_PROTO__ 0 +# endif + + +/* ---------------------------------------------------------------------- + * Functions from "". + */ + + +# ifdef _ERRNO_H +# define _errno_h 1 +# endif +# ifdef _errno_h +# if __MISS_GNU_PROTO__ + extern void perror __FP(( char* )); +# endif +# endif + + +/* ---------------------------------------------------------------------- + * Functions from "". + */ + + +# ifdef _SIGNAL_H +# define __signal_h 1 +# endif +# ifdef __signal_h +# if __MISS_GNU_PROTO__ + extern void (*ssignal())(); + extern int gsignal __FP(( int )); +# endif +# endif + + +/* ---------------------------------------------------------------------- + * Functions from "". + */ + + +# ifdef _SYS_UNISTD_H +# define __sys_unistd_h 1 +# endif +# ifdef __sys_unistd_h +# if __MISS_GNU_PROTO__ + extern int read __FP(( int, void*, __SIZE_TYPE__ )); +# endif +# endif + + +/* ---------------------------------------------------------------------- + * Functions from "". + */ + + +# ifdef _STDIO_H +# define __stdio_h 1 +# endif +# ifdef FILE +# define __stdio_h 1 +# endif +# ifdef __stdio_h +# if __MISS_GNU_PROTO__ + extern int fclose __FP(( FILE* )); + extern int fflush __FP(( FILE* )); + extern int printf __FP(( char*, ... )); + extern int fprintf __FP(( FILE*, char*, ... )); + extern int vfprintf __FP(( FILE*, char*, va_list )); + extern int vsprintf __FP(( char*, char*, va_list )); + extern int fputs __FP(( char*, FILE* )); +# endif +# endif + + +# endif diff --git a/alliance/src/sea/src/LEF_drive.c b/alliance/src/sea/src/LEF_drive.c new file mode 100644 index 00000000..3dadfd9d --- /dev/null +++ b/alliance/src/sea/src/LEF_drive.c @@ -0,0 +1,640 @@ +/* + * $Id: LEF_drive.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./LEF_drive.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" +# include "LEF_drive.h" + + +/* ------------------------------------------------------------------ + * Global variables (declared `extern' in "UtDefs.h"). + */ + + eMACRO_t *LEF_lMACRO = (eMACRO_t*)NULL; + + +/* ------------------------------------------------------------------ + * Internal functions declarations. + */ + + static char *CLASStoa __FP((char acCLASS)); + static char *DIRtoa __FP((char acDIR)); + static char *USEtoa __FP((char acUSE)); + static char *SHAPEtoa __FP((char acSHAPE)); + static char *LAYERtoa __FP((char acLAYER)); + static char *SYMMETRYtoa __FP((char acSYMMETRY)); + static char *pttoa __FP((XY_t *apXY)); + static char *SIZEtoa __FP((XY_t *apXY)); + static void fprintPATH __FP((FILE *LEF, ePATH_t *alPATH)); + static void fprintPORT __FP((FILE *LEF, ePORT_t *alPORT)); + static void fprintPIN __FP((FILE *LEF, ePIN_t *apPIN)); + static void fprintOBS __FP((FILE *LEF, eOBS_t *alOBS)); + + +/* + * /----------------------------------------------------------------\ + * | Functions Definitions | + * \----------------------------------------------------------------/ + */ + +/* ------------------------------------------------------------------ + * Function : "allocRECT()". + */ + +extern RECT_t *allocRECT(aX0, aY0, aX1, aY1) + long aX0, aY0, aX1, aY1; +{ + RECT_t *pRECT; + + pRECT = (RECT_t*)malloc(sizeof(RECT_t)); + pRECT->pt0.x = MBK2DEF_length (aX0); + pRECT->pt0.y = MBK2DEF_length (aY0); + pRECT->pt1.x = MBK2DEF_length (aX1); + pRECT->pt1.y = MBK2DEF_length (aY1); + + return(pRECT); +} + + +/* ------------------------------------------------------------------ + * Function : "allocPATH()". + */ + +extern ePATH_t *allocPATH(alPATH, aX, aY) + ePATH_t *alPATH; + long aX, aY; +{ + ePATH_t *pPATH; + + pPATH = (ePATH_t*)malloc(sizeof(ePATH_t)); + pPATH->pt.x = MBK2DEF_length (aX); + pPATH->pt.y = MBK2DEF_length (aY); + + /* Add the new element in head of list. */ + pPATH->Next = alPATH; + + return(pPATH); +} + + +/* ------------------------------------------------------------------ + * Function : "revPATH()". + */ + +extern ePATH_t *revPATH(apPATH) + ePATH_t *apPATH; +{ + ePATH_t *pPATH, *lRevPATH, *pTmp; + + + lRevPATH = (ePATH_t *)NULL; + + for(pPATH = apPATH; pPATH != (ePATH_t*)NULL;) { + + pTmp = pPATH; + pPATH = pPATH->Next; + + pTmp->Next = lRevPATH; + lRevPATH = pTmp; + + } /* End of "pPATH" loop. */ + + return(lRevPATH); +} + + +/* ------------------------------------------------------------------ + * Function : "allocOBS()". + */ + +extern eOBS_t *allocOBS(alOBS, aType, apData) + eOBS_t *alOBS; + char aType; + void *apData; +{ + eOBS_t *pOBS; + + pOBS = (eOBS_t*)malloc(sizeof(eOBS_t)); + pOBS->Type = aType; + + if (aType == C_OBSITEM_WIDTH) + pOBS->Data = (void*)(MBK2DEF_length ((long)apData)); + else + pOBS->Data = apData; + + /* Add the new element in head of list. */ + pOBS->Next = alOBS; + + return(pOBS); +} + + +/* ------------------------------------------------------------------ + * Function : "revOBS()". + */ + +extern eOBS_t *revOBS(apOBS) + eOBS_t *apOBS; +{ + eOBS_t *pOBS, *lRevOBS, *pTmp; + + + lRevOBS = (eOBS_t *)NULL; + + for(pOBS = apOBS; pOBS != (eOBS_t*)NULL;) { + + pTmp = pOBS; + pOBS = pOBS->Next; + + pTmp->Next = lRevOBS; + lRevOBS = pTmp; + + } /* End of "pOBS" loop. */ + + return(lRevOBS); +} + + +/* ------------------------------------------------------------------ + * Function : "allocPORT()". + */ + +extern ePORT_t *allocPORT(alPORT, aType, apData) + ePORT_t *alPORT; + char aType; + void *apData; +{ + ePORT_t *pPORT; + + pPORT = (ePORT_t*)malloc(sizeof(ePORT_t)); + pPORT->Type = aType; + + if (aType == C_PORTITEM_WIDTH) + pPORT->Data = (void*)(MBK2DEF_length ((long)apData)); + else + pPORT->Data = apData; + + /* Add the new element in head of list. */ + pPORT->Next = alPORT; + + return(pPORT); +} + + +/* ------------------------------------------------------------------ + * Function : "revPORT()". + */ + +extern ePORT_t *revPORT(apPORT) + ePORT_t *apPORT; +{ + ePORT_t *pPORT, *lRevPORT, *pTmp; + + + lRevPORT = (ePORT_t *)NULL; + + for(pPORT = apPORT; pPORT != (ePORT_t*)NULL;) { + + pTmp = pPORT; + pPORT = pPORT->Next; + + pTmp->Next = lRevPORT; + lRevPORT = pTmp; + + } /* End of "pPORT" loop. */ + + return(lRevPORT); +} + + +/* ------------------------------------------------------------------ + * Function : "allocPIN()". + */ + +extern ePIN_t *allocPIN(alPin, asName) + ePIN_t *alPin; + char *asName; +{ + ePIN_t *pPIN; + + /* Allocate, and for security'sake, blank all the fields. */ + pPIN = (ePIN_t*)malloc(sizeof(ePIN_t)); + pPIN->pinName = namealloc(asName); + pPIN->DIRECTION = C_DIRECTION_NONE; + pPIN->USE = C_USE_NONE; + pPIN->SHAPE = C_SHAPE_NONE; + pPIN->lPORT = (ePORT_t*)NULL; + + /* Add the new element in head of list. */ + pPIN->Next = alPin; + + return(pPIN); +} + + +/* ------------------------------------------------------------------ + * Function : "getPIN()". + */ + +extern ePIN_t *getPIN(apMACRO, asName) + eMACRO_t *apMACRO; + char *asName; +{ + ePIN_t *pPIN; + + + for(pPIN = apMACRO->lPIN; pPIN != (ePIN_t*)NULL; pPIN = pPIN->Next) { + if (pPIN->pinName == asName) return(pPIN); + } /* End of "pPIN" loop. */ + + return((ePIN_t*)NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "allocMACRO()". + */ + +extern eMACRO_t *allocMACRO(asName) + char *asName; +{ + eMACRO_t *pMACRO; + + /* Allocate, and for security'sake, blank all the fields. */ + pMACRO = (eMACRO_t*)malloc(sizeof(eMACRO_t)); + pMACRO->macroName = namealloc(asName); + pMACRO->CLASS = C_CLASS_NONE; + pMACRO->ORIGIN.x = 0L; + pMACRO->ORIGIN.y = 0L; + pMACRO->SIZE.x = 0L; + pMACRO->SIZE.y = 0L; + pMACRO->SYMMETRY = F_SYMMETRY_NONE; + pMACRO->SITE = (char*)NULL; + pMACRO->lPIN = (ePIN_t*)NULL; + pMACRO->lOBS = (eOBS_t*)NULL; + + /* Add the new element in head of list. */ + pMACRO->Next = LEF_lMACRO; + LEF_lMACRO = pMACRO; + + return(pMACRO); +} + + +/* ------------------------------------------------------------------ + * Function : "CLASStoa()". + */ + +static char *CLASStoa(acCLASS) + char acCLASS; +{ + switch(acCLASS) { + case C_CLASS_NONE: return((char*)NULL); + case C_CLASS_COVER: return("COVER"); + case C_CLASS_RING: return("RING"); + case C_CLASS_PAD: return("PAD"); + case C_CLASS_CORE: return("CORE"); + case C_CLASS_FEEDTHRU: return("CORE FEEDTHRU"); + case C_CLASS_ENDCAP: return("ENDCAP"); + case C_CLASS_TOPRIGHT: return("ENDCAP TOPRIGHT"); + case C_CLASS_TOPLEFT: return("ENDCAP TOPLEFT"); + } + + return((char*)NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "DIRtoa()". + */ + +static char *DIRtoa(acDIR) + char acDIR; +{ + switch(acDIR) { + case C_DIRECTION_NONE: return((char*)NULL); + case C_DIRECTION_INPUT: return("INPUT"); + case C_DIRECTION_OUTPUT: return("OUTPUT"); + case C_DIRECTION_TRISTATE: return("OUTPUT TRISTATE"); + case C_DIRECTION_INOUT: return("INOUT"); + case C_DIRECTION_FEEDTHRU: return("FEEDTHRU"); + } + + return((char*)NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "USEtoa()". + */ + +static char *USEtoa(acUSE) + char acUSE; +{ + switch(acUSE) { + case C_USE_NONE: return((char*)NULL); + case C_USE_SIGNAL: return("signal"); + case C_USE_ANALOG: return("analog"); + case C_USE_POWER: return("power"); + case C_USE_GROUND: return("ground"); + case C_USE_CLOCK: return("clock"); + } + + return((char*)NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "SHAPEtoa()". + */ + +static char *SHAPEtoa(acSHAPE) + char acSHAPE; +{ + switch(acSHAPE) { + case C_SHAPE_NONE: return((char*)NULL); + case C_SHAPE_ABUTMENT: return("ABUTMENT"); + case C_SHAPE_RING: return("RING"); + case C_SHAPE_FEEDTHRU: return("FEEDTHRU"); + } + + return((char*)NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "LAYERtoa()". + */ + +static char *LAYERtoa(acLAYER) + char acLAYER; +{ + switch(acLAYER) { + case ALU1: return("L_ALU1"); + case ALU2: return("L_ALU2"); + case ALU3: return("L_ALU3"); + case ALU4: return("L_ALU4"); + case ALU5: return("L_ALU5"); + case ALU6: return("L_ALU6"); + case CALU1: return("L_ALU1"); + case CALU2: return("L_ALU2"); + case CALU3: return("L_ALU3"); + case CALU4: return("L_ALU4"); + case CALU5: return("L_ALU5"); + case CALU6: return("L_ALU6"); + } + + return((char*)NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "SYMMETRYtoa()". + */ + +static char *SYMMETRYtoa(acSYMMETRY) + char acSYMMETRY; +{ + static char sSYMMETRY[32]; + int iSYMMETRY; + + iSYMMETRY = 0; + + if (acSYMMETRY & F_SYMMETRY_X) { + sSYMMETRY[iSYMMETRY++] = 'X'; sSYMMETRY[iSYMMETRY++] = ' '; } + + if (acSYMMETRY & F_SYMMETRY_Y) { + sSYMMETRY[iSYMMETRY++] = 'Y'; sSYMMETRY[iSYMMETRY++] = ' '; } + + if (acSYMMETRY & F_SYMMETRY_R90) { + strncpy(sSYMMETRY + iSYMMETRY, "r90 ", 4); + iSYMMETRY += 4; + } + + sSYMMETRY[iSYMMETRY - 1] = (char)0; + + return(sSYMMETRY); +} + + +/* ------------------------------------------------------------------ + * Function : "pttoa()". + */ + +static char *pttoa(apXY) + XY_t *apXY; +{ + static char sXY[32]; + + sprintf(sXY, "%.2f %.2f", MICRONS(apXY->x), MICRONS(apXY->y)); + + return(sXY); +} + + +/* ------------------------------------------------------------------ + * Function : "SIZEtoa()". + */ + +static char *SIZEtoa(apXY) + XY_t *apXY; +{ + static char sXY[32]; + + sprintf(sXY, "%.2f BY %.2f", MICRONS(apXY->x), MICRONS(apXY->y)); + + return(sXY); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintPATH()". + */ + +static void fprintPATH(LEF, alPATH) + FILE *LEF; + ePATH_t *alPATH; +{ + ePATH_t *pPATH; + + + fprintf(LEF, " PATH "); + + for(pPATH = alPATH; pPATH != (ePATH_t*)NULL; pPATH = pPATH->Next) { + fprintf(LEF, "%s ", pttoa(&(pPATH->pt))); + } /* End of "pPATH" loop. */ + + fprintf(LEF, ";\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintPORT()". + */ + +static void fprintPORT(LEF, alPORT) + FILE *LEF; + ePORT_t *alPORT; +{ + ePORT_t *pPORT; + + + fprintf(LEF, " PORT\n"); + + for(pPORT = alPORT; pPORT != (ePORT_t*)NULL; pPORT = pPORT->Next) { + switch(pPORT->Type) { + + case C_PORTITEM_LAYER: + fprintf(LEF, " LAYER %s ;\n", + LAYERtoa((char)(long)((pPORT->Data)))); + break; + + case C_PORTITEM_WIDTH: + fprintf(LEF, " WIDTH %.2f ;\n", + MICRONS((long)(pPORT->Data))); + break; + + case C_PORTITEM_RECT: + fprintf(LEF, " RECT %s ", + pttoa(&((RECT_t*)pPORT->Data)->pt0)); + + fprintf(LEF, "%s ;\n", pttoa(&((RECT_t*)pPORT->Data)->pt1)); + break; + + case C_PORTITEM_PATH: + fprintPATH(LEF, (ePATH_t *)pPORT->Data); + break; + + } /* End of "pPORT->Type" switch. */ + } /* End of "pPORT" loop. */ + + fprintf(LEF, " END\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintPIN()". + */ + +static void fprintPIN(LEF, apPIN) + FILE *LEF; + ePIN_t *apPIN; +{ + char *sPin, sPinLEF[80]; + + + sPin = MBK2DEF_name(sPinLEF, apPIN->pinName); + + fprintf(LEF, " PIN %s\n", sPin); + + if (apPIN->DIRECTION != C_DIRECTION_NONE) { + fprintf(LEF, " DIRECTION %s ;\n", DIRtoa(apPIN->DIRECTION)); } + + if (apPIN->USE != C_USE_NONE) { + fprintf(LEF, " USE %s ;\n", USEtoa(apPIN->USE)); } + + if (apPIN->SHAPE != C_SHAPE_NONE) { + fprintf(LEF, " SHAPE %s ;\n", SHAPEtoa(apPIN->SHAPE)); } + + if (apPIN->lPORT != (ePORT_t*)NULL) + fprintPORT(LEF, apPIN->lPORT); + + fprintf(LEF, " END %s\n", sPin); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintOBS()". + */ + +static void fprintOBS(LEF, alOBS) + FILE *LEF; + eOBS_t *alOBS; +{ + eOBS_t *pOBS; + + + if (alOBS != (eOBS_t*)NULL) fprintf(LEF, " OBS\n"); + + for(pOBS = alOBS; pOBS != (eOBS_t*)NULL; pOBS = pOBS->Next) { + switch(pOBS->Type) { + + case C_OBSITEM_LAYER: + fprintf(LEF, " LAYER %s ;\n", + LAYERtoa((char)(long)((pOBS->Data)))); + break; + + case C_OBSITEM_WIDTH: + fprintf(LEF, " WIDTH %.2f ;\n", + MICRONS((long)(pOBS->Data))); + break; + + case C_OBSITEM_RECT: + fprintf(LEF, " RECT %s ", + pttoa(&((RECT_t*)pOBS->Data)->pt0)); + + fprintf(LEF, "%s ;\n", pttoa(&((RECT_t*)pOBS->Data)->pt1)); + break; + + case C_OBSITEM_PATH: + fprintPATH(LEF, (ePATH_t *)pOBS->Data); + break; + + } /* End of "pOBS->Type" switch. */ + } /* End of "pOBS" loop. */ + + if (alOBS != (eOBS_t*)NULL) fprintf(LEF, " END\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "fprintMACRO()". + */ + +extern void fprintMACRO(LEF, apMACRO) + FILE *LEF; + eMACRO_t *apMACRO; +{ + ePIN_t *pPIN; + + + fprintf(LEF, "MACRO %s\n", apMACRO->macroName); + + + if (apMACRO->CLASS != C_CLASS_NONE) { + fprintf(LEF, " CLASS %s ;\n", CLASStoa(apMACRO->CLASS)); } + + fprintf(LEF, " ORIGIN %s ;\n", pttoa(&(apMACRO->ORIGIN))); + fprintf(LEF, " SIZE %s ;\n", SIZEtoa(&(apMACRO->SIZE ))); + + if (apMACRO->SYMMETRY != F_SYMMETRY_NONE) { + fprintf(LEF, " SYMMETRY %s ;\n", SYMMETRYtoa(apMACRO->SYMMETRY)); } + + if (apMACRO->SITE != (char*)NULL) { + fprintf(LEF, " SITE %s ;\n", apMACRO->SITE); } + + + for(pPIN = apMACRO->lPIN; pPIN != (ePIN_t *)NULL; pPIN = pPIN->Next) + fprintPIN(LEF, pPIN); + + + fprintOBS(LEF, apMACRO->lOBS); + + + fprintf(LEF, "END %s\n\n", apMACRO->macroName); +} diff --git a/alliance/src/sea/src/LEF_drive.h b/alliance/src/sea/src/LEF_drive.h new file mode 100644 index 00000000..eb19650e --- /dev/null +++ b/alliance/src/sea/src/LEF_drive.h @@ -0,0 +1,146 @@ +/* + * $Id: LEF_drive.h,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Header : "./LEF_drive.h" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# ifndef __LEF_drive__ +# define __LEF_drive__ + + +# define C_CLASS_NONE ((char)0) +# define C_CLASS_COVER ((char)1) +# define C_CLASS_RING ((char)2) +# define C_CLASS_PAD ((char)3) +# define C_CLASS_CORE ((char)4) +# define C_CLASS_FEEDTHRU ((char)5) +# define C_CLASS_ENDCAP ((char)6) +# define C_CLASS_TOPRIGHT ((char)7) +# define C_CLASS_TOPLEFT ((char)8) + +# define F_SYMMETRY_NONE ((char)0) +# define F_SYMMETRY_X ((char)1) +# define F_SYMMETRY_Y ((char)2) +# define F_SYMMETRY_R90 ((char)4) +# define F_SYMMETRY_XY ((char)( F_SYMMETRY_X \ + | F_SYMMETRY_Y )) +# define F_SYMMETRY_XYR90 ((char)( F_SYMMETRY_X \ + | F_SYMMETRY_Y \ + | F_SYMMETRY_R90 )) + +# define C_USE_NONE ((char)0) +# define C_USE_SIGNAL ((char)1) +# define C_USE_ANALOG ((char)2) +# define C_USE_POWER ((char)3) +# define C_USE_GROUND ((char)4) +# define C_USE_CLOCK ((char)5) + +# define C_SHAPE_NONE ((char)0) +# define C_SHAPE_ABUTMENT ((char)1) +# define C_SHAPE_RING ((char)2) +# define C_SHAPE_FEEDTHRU ((char)3) + +# define C_PORTITEM_LAYER ((char)1) +# define C_PORTITEM_WIDTH ((char)2) +# define C_PORTITEM_PATH ((char)3) +# define C_PORTITEM_RECT ((char)4) +# define C_OBSITEM_LAYER C_PORTITEM_LAYER +# define C_OBSITEM_WIDTH C_PORTITEM_WIDTH +# define C_OBSITEM_PATH C_PORTITEM_PATH +# define C_OBSITEM_RECT C_PORTITEM_RECT + + + typedef struct XY_s { long x; long y; } XY_t; + + + typedef struct ePATH_s { + struct XY_s pt; + struct ePATH_s *Next; + } ePATH_t; + + + typedef struct RECT_s { + struct XY_s pt0; + struct XY_s pt1; + } RECT_t; + + + typedef struct ePORT_s { + char Type; + void *Data; + struct ePORT_s *Next; + } ePORT_t; + + + typedef struct eOBS_s { + char Type; + void *Data; + struct eOBS_s *Next; + } eOBS_t; + + + typedef struct ePIN_s { + char *pinName; + char DIRECTION; + char USE; + char SHAPE; + struct ePORT_s *lPORT; + struct ePIN_s *Next; + } ePIN_t; + + + typedef struct eMACRO_s { + char *macroName; + char CLASS; + struct XY_s ORIGIN; + struct XY_s SIZE; + char SYMMETRY; + char *SITE; + struct ePIN_s *lPIN; + struct eOBS_s *lOBS; + struct eMACRO_s *Next; /* The next element... */ + } eMACRO_t; + + +# define MICRONS(m) (((float)(m)) / DEF_UNITS_MICRONS) + +# define m_AddPin(p,n) ((p) = allocPIN((p), (n))) +# define m_AddPort(p,t,d) ((p) = allocPORT((p), (t), (void*)(d))) +# define m_RevPort(p) ((p) = revPORT((p))) +# define m_AddObs(p,t,d) ((p) = allocOBS((p), (t), (void*)(d))) +# define m_RevObs(p) ((p) = revOBS((p))) + +# define m_AddRect(x0,y0,x1,y1) (allocRECT(x0, y0, x1, y1)) + +# define m_AddPath(p,x,y) ((p) = allocPATH((p), x, y)) + +# define m_RevPath(p) ((p) = revPATH((p))) + + + extern RECT_t *allocRECT __FP((long aX0, long aY0, long aX1, long aY1)); + extern ePATH_t *allocPATH __FP((ePATH_t *alPATH, long aX, long aY)); + extern ePATH_t *revPATH __FP((ePATH_t *apPATH)); + extern eOBS_t *allocOBS __FP((eOBS_t *alOBS, char aType, void *apData)); + extern eOBS_t *revOBS __FP((eOBS_t *apOBS)); + extern ePORT_t *allocPORT __FP((ePORT_t *alPORT, char aType, void *apData)); + extern ePORT_t *revPORT __FP((ePORT_t *apPORT)); + extern ePIN_t *allocPIN __FP((ePIN_t *alPin, char *asName)); + extern ePIN_t *getPIN __FP((eMACRO_t *apMACRO, char *asName)); + extern eMACRO_t *allocMACRO __FP((char *asName)); + extern void fprintMACRO __FP((FILE *LEF, eMACRO_t *apMACRO)); + + +# endif diff --git a/alliance/src/sea/src/LEF_drive_sxlib.c b/alliance/src/sea/src/LEF_drive_sxlib.c new file mode 100644 index 00000000..ed0f9a2c --- /dev/null +++ b/alliance/src/sea/src/LEF_drive_sxlib.c @@ -0,0 +1,1056 @@ +/* + * $Id: LEF_drive_sxlib.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./LEF_drive_sxlib.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" +# include "LEF_drive.h" +# include "LEF_drive_sxlib.h" + + +/* ------------------------------------------------------------------ + * Local constants. + */ + + +# define XGRID MBKSCALE(5) +# define YGRID MBKSCALE(5) +# define YSLICE MBKSCALE(50) +# define EXT_ALU1 MBKSCALE(0.5) +# define EXT_ALU2 MBKSCALE(1.0) +# define EXT_ALU3 MBKSCALE(1.0) +# define EXT_ALU4 MBKSCALE(1.0) +# define EXT_ALU5 MBKSCALE(1.0) +# define EXT_ALU6 MBKSCALE(1.0) +# define WIDTH_CALUx MBKSCALE(2) +# define MIN_WIDTH_ALU1 MBKSCALE(1) +# define WIDTH_OBS_ALU1 MBKSCALE(2) +# define HEIGHT_OBS_ALU1 MBKSCALE(2) +# define LEFTRIGHT_OBS_ALU1 MBKSCALE(2.5) +# define F_POWER_PIN_LEFT 0x00000001 +# define F_POWER_PIN_RIGHT 0x00000002 + + +/* ------------------------------------------------------------------ + * Internal structures definitions. + */ + + typedef struct eGrid_s { + long x; + long y; + struct eGrid_s *Next; + } eGrid_t; + + +/* ------------------------------------------------------------------ + * Local variables (prefix 'LV_'). + */ + + + static phfig_list *LV_phfig; /* Working physical figure. */ + static lofig_list *LV_lofig; /* Working logical figure. */ + static eMACRO_t *LV_pMACRO; + static eGrid_t *LV_tHolesALU1 = (eGrid_t*)NULL; + static char *LV_ref_ref; /* Pointer to the "ref_ref" string. */ + static char *LV_ref_con; /* Pointer to the "ref_con" string. */ + static long LV_flags; /* Conversion flags. */ + + +/* ------------------------------------------------------------------ + * Internal functions declarations. + */ + +static long getLayerExt __FP((char aLayer)); +static eGrid_t *getTGrid __FP((eGrid_t **aptGrid, long aX, long aY)); +static eGrid_t *addTGrid __FP((eGrid_t **aptGrid, long aX, long aY)); +static void phseg2TGrid __FP((eGrid_t **aptGrid, + phseg_list *apPhSeg)); +static void TGrid2PORT __FP((ePORT_t **aplPORT, eGrid_t *aptGrid)); +static char *refCon2Name __FP((char *asRefCon)); +static int onGrid __FP((long aX, long aY)); +static locon_list *getLoCon __FP((char *asName)); +static void SxLib2SYMMETRY __FP((void)); +static void AddEmptyPowerPIN __FP((char *asName)); +static void AddPowerPIN __FP((char *asName, + char aDir, + char aLayer, + long aY, + long aWidth, + long aFlags)); +static void SxLib2PowerPINS __FP((char aLayer, + char aDir, + char *asSuffix)); +static void phref2PINS __FP((void)); +static void phseg2PINS __FP((void)); +static void SxLib2SignalPINS __FP((void)); +static void insertPIN __FP((ePIN_t **appHead, + ePIN_t **appTail, + ePIN_t *apPIN)); +static void sortPINS __FP((void)); +static void checkPIN __FP((void)); +# if 0 +static void SxLib2ALU1OBS __FP((void)); +# endif +static void SxLib2ALUxOBS __FP((char aLayer)); +static void revPINPORT __FP((void)); +static eMACRO_t *SxLib2MACRO __FP((void)); + + +/* + * /--------------------------------------------------------------------\ + * | Functions Definitions | + * \--------------------------------------------------------------------/ + */ + + +/* ---------------------------------------------------------------------- + * Function : "getLayerExt()". + */ + +static long getLayerExt(aLayer) + char aLayer; +{ + switch(aLayer) { + case ALU1: return(EXT_ALU1); + case ALU2: return(EXT_ALU2); + case ALU3: return(EXT_ALU3); + case ALU4: return(EXT_ALU4); + case ALU5: return(EXT_ALU5); + case ALU6: return(EXT_ALU6); + } + + return(0L); +} + + +/* ---------------------------------------------------------------------- + * Function : "getTGrid()". + */ + +static eGrid_t *getTGrid(aptGrid, aX, aY) + eGrid_t **aptGrid; + long aX, aY; +{ + eGrid_t *pGrid; + + + for(pGrid = *aptGrid; pGrid != (eGrid_t*)NULL; pGrid = pGrid->Next) + if ((pGrid->x == aX) && (pGrid->y == aY)) return(pGrid); + + return((eGrid_t*)NULL); +} + + +/* ---------------------------------------------------------------------- + * Function : "addTGrid()". + */ + +static eGrid_t *addTGrid(aptGrid, aX, aY) + eGrid_t **aptGrid; + long aX, aY; +{ + eGrid_t *pGrid; + + + pGrid = getTGrid(aptGrid, aX, aY); + if (pGrid != (eGrid_t*)NULL) return(pGrid); + + pGrid = (eGrid_t*)malloc(sizeof(eGrid_t)); + pGrid->x = aX; + pGrid->y = aY; + + pGrid->Next = *aptGrid; + *aptGrid = pGrid; + + return(pGrid); +} + + +/* ---------------------------------------------------------------------- + * Function : "phseg2TGrid()". + */ + +static void phseg2TGrid(aptGrid, apPhSeg) + eGrid_t **aptGrid; + phseg_list *apPhSeg; +{ + long y, yMin, yMax; + + + if (apPhSeg->X1 == apPhSeg->X2) { + if (!(LV_flags & F_ALLOW_OFFGRID)) { + if ((apPhSeg->X1 - LV_phfig->XAB1) % XGRID) { + wprinth((char*)NULL); + wprintf("Segment \"%s\" (%d,%d) (%d,%d) is NOT on grid (skipped).\n", + apPhSeg->NAME, apPhSeg->X1, apPhSeg->Y1, + apPhSeg->X2, apPhSeg->Y2); + return; + } + } + + yMax = apPhSeg->Y2 - (apPhSeg->Y2 % YGRID); + yMin = apPhSeg->Y1; + if (apPhSeg->Y1 % YGRID) yMin += YGRID - (apPhSeg->Y1 % YGRID); + + for(y = yMin; y <= yMax; y += YGRID) { + addTGrid(aptGrid, apPhSeg->X1, y); + } + } else { + if (!(LV_flags & F_ALLOW_OFFGRID)) { + if ((apPhSeg->Y1 - LV_phfig->YAB1) % YGRID) { + wprinth((char*)NULL); + wprintf("Segment \"%s\" (%d,%d) (%d,%d) is NOT on grid (skipped).\n", + apPhSeg->NAME, apPhSeg->X1, apPhSeg->Y1, + apPhSeg->X2, apPhSeg->Y2); + return; + } + } + + yMax = apPhSeg->X2 - (apPhSeg->X2 % XGRID); + yMin = apPhSeg->X1; + if (apPhSeg->X1 % XGRID) yMin += XGRID - (apPhSeg->X1 % XGRID); + + for(y = yMin; y <= yMax; y += XGRID) { + addTGrid(aptGrid, y, apPhSeg->Y1); + } + } +} + + +/* ---------------------------------------------------------------------- + * Function : "TGrid2PORT()". + */ + +static void TGrid2PORT(aplPORT, aptGrid) + ePORT_t **aplPORT; + eGrid_t *aptGrid; +{ + eGrid_t *pGrid; + + + for(pGrid = aptGrid; pGrid != NULL; pGrid = pGrid->Next) { + m_AddPort((*aplPORT), C_PORTITEM_RECT, + m_AddRect(pGrid->x - WIDTH_CALUx / 2, + pGrid->y - WIDTH_CALUx / 2, + pGrid->x + WIDTH_CALUx / 2, + pGrid->y + WIDTH_CALUx / 2)); + } /* End of "pGrid" loop. */ +} + + +/* ---------------------------------------------------------------------- + * Function : "refCon2Name()". + */ + +static char *refCon2Name(asRefCon) + char *asRefCon; +{ + char *c, *e, sIOName[1024]; + + + strcpy(sIOName, asRefCon); + + for(e = (char*)NULL, c = sIOName; *c != (char)0; c++) + if (*c == '_') e = c; + + if (e != (char*)NULL) *e = (char)0; + + + return(namealloc(sIOName)); +} + + +/* ---------------------------------------------------------------------- + * Function : "onGrid()". + */ + +static int onGrid(aX, aY) + long aX, aY; +{ + if ((aX - LV_phfig->XAB1) % XGRID) return(FALSE); + if ((aY - LV_phfig->YAB1) % YGRID) return(FALSE); + + return(TRUE); +} + + +/* ---------------------------------------------------------------------- + * Function : "getLoCon()". + */ + +static locon_list *getLoCon(asName) + char *asName; +{ + locon_list *pLoCon; + + + for(pLoCon = LV_lofig->LOCON; + pLoCon != (locon_list*)NULL; + pLoCon = pLoCon->NEXT) { + if (pLoCon->NAME == asName) return(pLoCon); + } + + /* No matching locon found. */ + return((locon_list *)NULL); +} + + +/* ---------------------------------------------------------------------- + * Function : "SxLib2SYMMETRY()". + */ + +static void SxLib2SYMMETRY() +{ + /* Symmetry generation. */ + if (((LV_phfig->YAB2 - LV_phfig->YAB1) / YSLICE) % 2) { + LV_pMACRO->SYMMETRY = F_SYMMETRY_XY; + } else { + LV_pMACRO->SYMMETRY = F_SYMMETRY_Y; + } +} + + +/* ---------------------------------------------------------------------- + * Function : "AddEmptyPowerPIN()". + */ + +static void AddEmptyPowerPIN(asName) + char *asName; +{ + ePIN_t *pPIN; + char Use; + + + Use = C_USE_NONE; + if (!strncmp(asName, "vdd", 3)) Use = C_USE_POWER; + if (!strncmp(asName, "vss", 3)) Use = C_USE_GROUND; + + + if ((pPIN = getPIN(LV_pMACRO, asName)) == (ePIN_t*)NULL) { + m_AddPin(LV_pMACRO->lPIN, asName); + LV_pMACRO->lPIN->DIRECTION = C_DIRECTION_INOUT; + LV_pMACRO->lPIN->USE = Use; + LV_pMACRO->lPIN->SHAPE = C_SHAPE_FEEDTHRU; + } +} + + +/* ---------------------------------------------------------------------- + * Function : "AddPowerPIN()". + */ + +static void AddPowerPIN(asName, aDir, aLayer, aY, aWidth, aFlags) + char *asName; + char aLayer, aDir; + long aY, aWidth, aFlags; +{ + ePATH_t *pPATH; + ePIN_t *pPIN; + char Use, Shape; + long XO1, XO2, YO1, YO2; + + + pPIN = NULL; /* Shut up "gcc -w" ... */ + + if (aFlags) { + /* Either left or right terminal is asked or both, we need to create + * a PIN if it's not already present. + */ + Use = C_USE_NONE; + if (!strncmp(asName, "vdd", 3)) Use = C_USE_POWER; + if (!strncmp(asName, "vss", 3)) Use = C_USE_GROUND; + + Shape = C_SHAPE_FEEDTHRU; + if (LV_flags & F_POWER_ABUTMENT) + Shape = C_SHAPE_ABUTMENT; + + if ((pPIN = getPIN(LV_pMACRO, asName)) == (ePIN_t*)NULL) { + m_AddPin(LV_pMACRO->lPIN, asName); + LV_pMACRO->lPIN->DIRECTION = C_DIRECTION_INOUT; + LV_pMACRO->lPIN->USE = Use; + LV_pMACRO->lPIN->SHAPE = Shape; + + pPIN = LV_pMACRO->lPIN; + } + + m_AddPort(pPIN->lPORT, C_PORTITEM_LAYER, (long)aLayer); + m_AddPort(pPIN->lPORT, C_PORTITEM_WIDTH, aWidth); + } + + if (aFlags && (LV_flags & F_POWER_ABUTMENT)) { + pPATH = (ePATH_t *)NULL; + + switch(aDir) { + default: + case C_POWER_HORIZONTAL: + m_AddPath(pPATH, LV_phfig->XAB1 + aWidth / 2, aY); + m_AddPath(pPATH, LV_phfig->XAB2 - aWidth / 2, aY); + break; + case C_POWER_VERTICAL: + m_AddPath(pPATH, aY, LV_phfig->YAB1 + aWidth / 2); + m_AddPath(pPATH, aY, LV_phfig->YAB2 - aWidth / 2); + break; + } + + m_AddPort(pPIN->lPORT, C_PORTITEM_PATH, revPATH(pPATH)); + } else { + switch(aDir) { + default: + case C_POWER_HORIZONTAL: + if (aFlags & F_POWER_PIN_LEFT) { + pPATH = (ePATH_t *)NULL; + + m_AddPath(pPATH, LV_phfig->XAB1 + aWidth / 2, aY); + m_AddPath(pPATH, LV_phfig->XAB1 + MBKSCALE(4) + aWidth / 2, aY); + + m_AddPort(pPIN->lPORT, C_PORTITEM_PATH, revPATH(pPATH)); + } + + if (aFlags & F_POWER_PIN_RIGHT) { + pPATH = (ePATH_t *)NULL; + + m_AddPath(pPATH, LV_phfig->XAB2 - MBKSCALE(4) - aWidth / 2, aY); + m_AddPath(pPATH, LV_phfig->XAB2 - aWidth / 2, aY); + + m_AddPort(pPIN->lPORT, C_PORTITEM_PATH, revPATH(pPATH)); + } + + if (aLayer == ALU1) { + XO1 = LV_phfig->XAB1 + ((aFlags & F_POWER_PIN_LEFT) + ? MBKSCALE(13) + : MBK_ALU1_SPACING / 2); + XO2 = LV_phfig->XAB2 - ((aFlags & F_POWER_PIN_RIGHT) + ? MBKSCALE(13) + : MBK_ALU1_SPACING / 2); + YO1 = aY - aWidth / 2; + YO2 = aY + aWidth / 2; + + m_AddObs(LV_pMACRO->lOBS, C_OBSITEM_RECT, + m_AddRect(XO1, YO1, XO2, YO2)); + } + break; + case C_POWER_VERTICAL: + pPATH = (ePATH_t *)NULL; + + m_AddPath(pPATH, aY, LV_phfig->YAB1 + aWidth / 2); + m_AddPath(pPATH, aY, LV_phfig->YAB1 + MBKSCALE(4) + aWidth / 2); + + m_AddPort(pPIN->lPORT, C_PORTITEM_PATH, revPATH(pPATH)); + pPATH = (ePATH_t *)NULL; + + m_AddPath(pPATH, aY, LV_phfig->YAB2 - MBKSCALE(4) - aWidth / 2); + m_AddPath(pPATH, aY, LV_phfig->YAB2 - aWidth / 2); + + m_AddPort(pPIN->lPORT, C_PORTITEM_PATH, revPATH(pPATH)); + break; + } + } +} + + +/* ---------------------------------------------------------------------- + * Function : "SxLib2PowerPINS()". + */ + +static void SxLib2PowerPINS(aLayer, aDir, asSuffix) + char aLayer; + char aDir; + char *asSuffix; +{ + ePow_t *pPow, *plPow; + char sTmp[32], *name; + long XO1, XO2, YO1, YO2, width_top, width_bottom, flags; + + + plPow = buildPow (LV_phfig, aLayer, aDir, asSuffix); + + + if (plPow == (ePow_t*)NULL) { + if (aLayer == ALU1) { + wprinth((char*)NULL); + wprints("\n Can't find any ALU1 power terminals! If this is not a bug"); + wprints(" please consider\n usage of \"-p\" flag.\n"); + } + + return; + } + + + if (aLayer == ALU1) { + if (plPow->Type != C_POWER_ISVSS) { + eprinth (NULL); + eprintf ("\n Bottom power supply is not VSS.\n"); + EXIT (1); + } + } + + + LV_flags |= F_POWER_ABUTMENT; + LV_flags &= ~F_POWER_FEEDTHRU; + + for (pPow = plPow; pPow != NULL; pPow = pPow->Next) { + if (!(pPow->flags & F_POWER_COMPLETE)) { + LV_flags &= ~F_POWER_ABUTMENT; + LV_flags |= F_POWER_FEEDTHRU; + break; + } + } + + + if (aLayer == ALU1) + m_AddObs(LV_pMACRO->lOBS, C_OBSITEM_LAYER, ALU1); + + + /* Power pin generation. */ + for (pPow = plPow; pPow != NULL; pPow = pPow->Next) { + switch (pPow->Type) { + case C_POWER_ISVDD: + /* + * Doesn't exist under SunOS 4.1.4. + * + * snprintf(sTmp, 31, "vdd%s", asSuffix); + */ + sprintf (sTmp, "vdd%s", asSuffix); + name = namealloc (sTmp); + width_bottom = MBK_WIDTH_VDD; + width_top = MBK_WIDTH_VSS; + + break; + default: + case C_POWER_ISVSS: + /* snprintf(sTmp, 31, "vss%s", asSuffix); + */ + sprintf (sTmp, "vss%s", asSuffix); + name = namealloc (sTmp); + width_bottom = MBK_WIDTH_VSS; + width_top = MBK_WIDTH_VDD; + break; + } + + flags = F_POWER_PIN_LEFT | F_POWER_PIN_RIGHT; + + if (aLayer == ALU1) { + if (pPow->min != LV_phfig->XAB1) flags &= ~F_POWER_PIN_LEFT; + if (pPow->max != LV_phfig->XAB2) flags &= ~F_POWER_PIN_RIGHT; + printf ("max %ld XAB2 %ld\n", pPow->max, LV_phfig->XAB2); + } + AddPowerPIN (name, aDir, aLayer, pPow->y, pPow->w, flags); + + /* In case of ALU1 layer add one big obstacle. */ + if ((aLayer == ALU1) && (pPow->Next != NULL)) { + if (pPow->Next->y - pPow->y > + MBK_ALU1_SPACING + (width_bottom + width_top) / 2) { + XO1 = LV_phfig->XAB1 + MBK_ALU1_SPACING / 2; + XO2 = LV_phfig->XAB2 - MBK_ALU1_SPACING / 2; + YO1 = pPow->y + MBK_ALU1_SPACING + width_bottom / 2; + YO2 = pPow->Next->y - MBK_ALU1_SPACING - width_top / 2; + + m_AddObs(LV_pMACRO->lOBS, C_OBSITEM_RECT, + m_AddRect(XO1, YO1, XO2, YO2)); + } + } + } /* End of "pPow" loop. */ + + + freePow (plPow); +} + + +/* ---------------------------------------------------------------------- + * Function : "phref2PINS()". + */ + +static void phref2PINS() +{ + phref_list *pPhRef; + locon_list *pLoCon; + ePIN_t *pPIN; + char *sIOName; + + + for(pPhRef = LV_phfig->PHREF; + pPhRef != (phref_list*)NULL; + pPhRef = pPhRef->NEXT) { + if (pPhRef->FIGNAME == LV_ref_con) { + + /* Get the IO name from the "ref_con" name. */ + sIOName = refCon2Name(pPhRef->NAME); + + /* Find the IO in the behavioral view. */ + if ((pLoCon = getLoCon(sIOName)) == (locon_list*)NULL) { + wprinth((char*)NULL); + wprintf( + "\n Physical terminal \"%s\" doesn't match any ", pPhRef->NAME); + wprints("logical terminal.\n"); + + continue; + } + + /* Skip connectors not on routing grid. */ + if (!onGrid(pPhRef->XREF, pPhRef->YREF)) { + wprinth((char*)NULL); + wprintf("Terminal \"%s\" is NOT on routing grid, skipped.\n", + pPhRef->NAME); + + continue; + } + + /* Add to the list of holes in the obstacle grid. */ + addTGrid(&LV_tHolesALU1, pPhRef->XREF, pPhRef->YREF); + + if ((pPIN = getPIN(LV_pMACRO, sIOName)) == (ePIN_t*)NULL) { + + /* Create a new pin named from "sIOName". */ + m_AddPin(LV_pMACRO->lPIN, sIOName); + LV_pMACRO->lPIN->DIRECTION = MBK2DEF_locondir(pLoCon); + m_AddPort(LV_pMACRO->lPIN->lPORT, C_PORTITEM_LAYER, ALU1); + + pPIN = LV_pMACRO->lPIN; + } + + m_AddPort(pPIN->lPORT, C_PORTITEM_RECT, + m_AddRect(pPhRef->XREF - WIDTH_CALUx / 2, + pPhRef->YREF - WIDTH_CALUx / 2, + pPhRef->XREF + WIDTH_CALUx / 2, + pPhRef->YREF + WIDTH_CALUx / 2)); + } + } /* End of "pPhRef" loop. */ +} + + +/* ---------------------------------------------------------------------- + * Function : "phseg2PINS()". + */ + +static void phseg2PINS() +{ + phseg_list *pPhSeg; + locon_list *pLoCon; + ePIN_t *pPIN; + eGrid_t *tCALU; + + + for(pPhSeg = LV_phfig->PHSEG; + pPhSeg != (phseg_list*)NULL; + pPhSeg = pPhSeg->NEXT) { + if (isvdd(pPhSeg->NAME)) continue; + if (isvss(pPhSeg->NAME)) continue; + + switch(pPhSeg->LAYER) { + case CALU1: + case CALU2: + case CALU3: + case CALU4: + case CALU5: + case CALU6: + /* Find the IO in the behavioral view. */ + if ((pLoCon = getLoCon(pPhSeg->NAME)) == (locon_list*)NULL) { + wprinth((char*)NULL); + wprintf( + "\n Physical terminal \"%s\" doesn't match any ", pPhSeg->NAME); + wprints("logical terminal.\n"); + + continue; + } + + tCALU = (eGrid_t*)NULL; + phseg2TGrid(&tCALU, pPhSeg); + + if ((pPIN = getPIN(LV_pMACRO, pPhSeg->NAME)) == (ePIN_t*)NULL) { + /* Create a new pin named from "pPhSeg->NAME". */ + m_AddPin(LV_pMACRO->lPIN, pPhSeg->NAME); + LV_pMACRO->lPIN->DIRECTION = MBK2DEF_locondir(pLoCon); + + pPIN = LV_pMACRO->lPIN; + } + + m_AddPort(pPIN->lPORT, C_PORTITEM_LAYER, (long)pPhSeg->LAYER); + TGrid2PORT(&(pPIN->lPORT), tCALU); + + break; + } /* End of "pPhSeg->LAYER" switch. */ + } /* End of "pPhSeg" loop. */ +} + + +/* ---------------------------------------------------------------------- + * Function : "SxLib2SignalPINS()". + */ + +static void SxLib2SignalPINS() +{ + phref2PINS(); + phseg2PINS(); +} + + +/* ---------------------------------------------------------------------- + * Function : "insertPIN()". + */ + +static void insertPIN(appHead, appTail, apPIN) + ePIN_t **appHead, **appTail; + ePIN_t *apPIN; +{ + if (*appHead == (ePIN_t*)NULL) { + *appHead = apPIN; + } else { + (*appTail)->Next = apPIN; + } + + *appTail = apPIN; + (*appTail)->Next = (ePIN_t*)NULL; +} + + +/* ---------------------------------------------------------------------- + * Function : "sortPINS()". + */ + +static void sortPINS() +{ + ePIN_t *pPIN, *pTmp, **ppHead; + ePIN_t *pHeadINOUT , *pTailINOUT; + ePIN_t *pHeadOUTPUT, *pTailOUTPUT; + ePIN_t *pHeadINPUT , *pTailINPUT; + ePIN_t *pHeadPOWER , *pTailPOWER; + + + pHeadINOUT = pTailINOUT = (ePIN_t*)NULL; + pHeadOUTPUT = pTailOUTPUT = (ePIN_t*)NULL; + pHeadINPUT = pTailINPUT = (ePIN_t*)NULL; + pHeadPOWER = pTailPOWER = (ePIN_t*)NULL; + + for(pPIN = LV_pMACRO->lPIN; pPIN != (ePIN_t*)NULL;) { + pTmp = pPIN; + pPIN = pPIN->Next; + + switch(pTmp->USE) { + case C_USE_POWER: + case C_USE_GROUND: + insertPIN(&pHeadPOWER, &pTailPOWER, pTmp); + continue; + } /* End of "USE" switch. */ + + switch(pTmp->DIRECTION) { + case C_DIRECTION_INPUT: + insertPIN(&pHeadINPUT, &pTailINPUT, pTmp); + continue; + case C_DIRECTION_OUTPUT: + case C_DIRECTION_TRISTATE: + insertPIN(&pHeadOUTPUT, &pTailOUTPUT, pTmp); + continue; + case C_DIRECTION_INOUT: + case C_DIRECTION_FEEDTHRU: + insertPIN(&pHeadINOUT, &pTailINOUT, pTmp); + continue; + } /* End of "DIRECTION" switch. */ + + eprinth((char*)NULL); + eprintf("\n Pin \"%s\" have no DIRECTION!?\n", pTmp->pinName); + EXIT(1); + } /* End of "pPIN" loop. */ + + /* Rebuild the complete list (in reverse order). */ + ppHead = &(LV_pMACRO->lPIN); + + if (pHeadINOUT != (ePIN_t*)NULL) { + *ppHead = pHeadINOUT; ppHead = &(pTailINOUT->Next); + } + + if (pHeadOUTPUT != (ePIN_t*)NULL) { + *ppHead = pHeadOUTPUT; ppHead = &(pTailOUTPUT->Next); + } + + if (pHeadINPUT != (ePIN_t*)NULL) { + *ppHead = pHeadINPUT; ppHead = &(pTailINPUT->Next); + } + + if (pHeadPOWER != (ePIN_t*)NULL) { + *ppHead = pHeadPOWER; ppHead = &(pTailPOWER->Next); + } + + *ppHead = (ePIN_t*)NULL; +} + + +/* ---------------------------------------------------------------------- + * Function : "revPINPORT()". + */ + +static void revPINPORT() +{ + ePIN_t *pPIN; + + for(pPIN = LV_pMACRO->lPIN; pPIN != (ePIN_t*)NULL; pPIN = pPIN->Next) { + m_RevPort(pPIN->lPORT); + } +} + + +/* ---------------------------------------------------------------------- + * Function : "checkPIN()". + */ + +static void checkPIN() +{ + ePIN_t *pPIN; + ePORT_t *pPORT; + locon_list *pLoCon; + long fError, fPORT; + + + fError = FALSE; + for(pLoCon = LV_lofig->LOCON; + pLoCon != (locon_list*)NULL; + pLoCon = pLoCon->NEXT) { + if (isvdd(pLoCon->NAME)) continue; + if (isvss(pLoCon->NAME)) continue; + + fPORT = FALSE; + + pPIN = getPIN(LV_pMACRO, pLoCon->NAME); + if (pPIN == (ePIN_t*)NULL) { + fError = TRUE; + + eprinth((char*)NULL); + eprintf("\n Logical terminal \"%s\" ", pLoCon->NAME); + eprints("have no physical terminal.\n\n"); + } else { + for(pPORT = pPIN->lPORT; pPORT != NULL; pPORT = pPORT->Next) { + switch(pPORT->Type) { + case C_PORTITEM_RECT: + case C_PORTITEM_PATH: fPORT = TRUE; + } + } + } + + if (fPORT || fError) continue; + + eprinth((char*)NULL); + eprintf("\n Terminal \"%s\" ", pLoCon->NAME); + + if (LV_flags & F_ALLOW_OFFGRID) { + eprints("have no terminals either on grid or offgrid."); + eprints("\n This must be a program bug.\n\n"); + } else + eprints("have no terminals on grid.\n\n"); + fError = TRUE; + } + + if (fError) EXIT(1); +} + + +# if 0 +/* ---------------------------------------------------------------------- + * Function : "SxLib2ALU1OBS()". + */ + +static void SxLib2ALU1OBS() +{ + long XO1, YO1, XO2, YO2; + long iX, iY, iTrack; + + + if (LV_phfig->XAB2 - LV_phfig->XAB1 < 2 * MBK_ALU1_SPACING) + return; + + XO1 = LV_phfig->XAB1 + MBK_ALU1_SPACING; + XO2 = LV_phfig->XAB2 - MBK_ALU1_SPACING; + YO1 = LV_phfig->YAB1 + MBK_ALU1_SPACING + MBK_WIDTH_VSS; + YO2 = LV_phfig->YAB2 - MBK_ALU1_SPACING - MBK_WIDTH_VDD; + + m_AddObs(LV_pMACRO->lOBS, C_OBSITEM_LAYER, ALU1); + m_AddObs(LV_pMACRO->lOBS, C_OBSITEM_RECT, + m_AddRect(XO1, YO1, XO2, YO2)); + + + /* We replace all the "dot" obstacles by one big. */ + for(iY = LV_phfig->YAB1 + (2 * YGRID); + iY < LV_phfig->YAB2 - YGRID ; iY += YGRID) { + + /* Do not put obstacles under the power supplies. */ + iTrack = ((iY - LV_phfig->YAB1) % YSLICE) / YGRID; + if ((iTrack < 2) || (iTrack > 8)) continue; + + for(iX = LV_phfig->XAB1 + XGRID; + iX < LV_phfig->XAB2; iX += XGRID) { + /*if (getTGrid(&LV_tHolesALU1, iX, iY) != (eGrid_t*)NULL) continue;*/ + + XO1 = iX - WIDTH_OBS_ALU1 / 2; + YO1 = iY - HEIGHT_OBS_ALU1 / 2; + XO2 = iX + WIDTH_OBS_ALU1 / 2; + YO2 = iY + HEIGHT_OBS_ALU1 / 2; + + if (iX == LV_phfig->XAB1 + XGRID) XO1 -= LEFTRIGHT_OBS_ALU1; + if (iX == LV_phfig->XAB2 - XGRID) XO2 += LEFTRIGHT_OBS_ALU1; + + m_AddObs(LV_pMACRO->lOBS, C_OBSITEM_RECT, + m_AddRect(XO1, YO1, XO2, YO2)); + } /* End of "iX" loop. */ + } /* End of "iY" loop. */ +} +# endif + + +/* ---------------------------------------------------------------------- + * Function : "SxLib2ALUxOBS()". + */ + +static void SxLib2ALUxOBS(aLayer) + char aLayer; +{ + phseg_list *pPhSeg; + long fComp, fFirst, X1, Y1, X2, Y2, Ext; + + + Ext = getLayerExt(aLayer); + + fFirst = TRUE; + + + for(pPhSeg = LV_phfig->PHSEG; pPhSeg != NULL; pPhSeg = pPhSeg->NEXT) { + fComp = cmpALU(aLayer, pPhSeg->LAYER); + + if (!(fComp & F_EQUAL)) continue; + if ( fComp & F_CALU ) continue; + + switch(pPhSeg->TYPE) { + case LEFT: + case RIGHT: + default: + X1 = pPhSeg->X1 - Ext; + X2 = pPhSeg->X2 + Ext; + Y1 = pPhSeg->Y1 - pPhSeg->WIDTH / 2; + Y2 = pPhSeg->Y2 + pPhSeg->WIDTH / 2; + break; + case UP: + case DOWN: + X1 = pPhSeg->X1 - pPhSeg->WIDTH / 2; + X2 = pPhSeg->X2 + pPhSeg->WIDTH / 2; + Y1 = pPhSeg->Y1 - Ext; + Y2 = pPhSeg->Y2 + Ext; + break; + } /* End of "pPhSeg->TYPE" switch. */ + + if (fFirst) { + fFirst = FALSE; + m_AddObs(LV_pMACRO->lOBS, C_OBSITEM_LAYER, (long)aLayer); + } + + m_AddObs(LV_pMACRO->lOBS, C_OBSITEM_RECT, m_AddRect(X1, Y1, X2, Y2)); + } /* End of "pPhSeg" loop. */ +} + + +/* ---------------------------------------------------------------------- + * Function : "SxLib2MACRO()". + */ + +static eMACRO_t *SxLib2MACRO() +{ + /* Shift the cell so that the AB is at (0,0). */ + shiftphfig (LV_phfig, -LV_phfig->XAB1, -LV_phfig->YAB1); + + LV_pMACRO = allocMACRO(LV_phfig->NAME); + + if ( strncmp(LV_phfig->NAME, "tie_", 4) + && strncmp(LV_phfig->NAME, "rowend_", 4)) + LV_pMACRO->CLASS = C_CLASS_CORE; + else + LV_pMACRO->CLASS = C_CLASS_FEEDTHRU; + + LV_pMACRO->ORIGIN.x = 0; + LV_pMACRO->ORIGIN.y = 0; + /* + * LV_pMACRO->ORIGIN.x = - MBK2DEF_length(LV_phfig->XAB1); + * LV_pMACRO->ORIGIN.y = - MBK2DEF_length(LV_phfig->YAB1); + */ + LV_pMACRO->SIZE.x = MBK2DEF_length(LV_phfig->XAB2 - LV_phfig->XAB1); + LV_pMACRO->SIZE.y = MBK2DEF_length(LV_phfig->YAB2 - LV_phfig->YAB1); + LV_pMACRO->SITE = "core"; + + SxLib2SYMMETRY(); + + if (LV_flags & F_NO_POWER_GEOM) { + long XO1, XO2, YO1, YO2; + + AddEmptyPowerPIN("vdd"); + AddEmptyPowerPIN("vss"); + + m_AddObs(LV_pMACRO->lOBS, C_OBSITEM_LAYER, ALU1); + + XO1 = LV_phfig->XAB1 + MBK_ALU1_SPACING / 2; + XO2 = LV_phfig->XAB2 - MBK_ALU1_SPACING / 2; + YO1 = LV_phfig->YAB1 + MBK_ALU1_SPACING / 2; + YO2 = LV_phfig->YAB2 - MBK_ALU1_SPACING / 2; + + m_AddObs(LV_pMACRO->lOBS, C_OBSITEM_RECT, + m_AddRect(XO1, YO1, XO2, YO2)); + } else { + SxLib2PowerPINS(ALU1, C_POWER_HORIZONTAL, ""); + SxLib2PowerPINS(ALU3, C_POWER_VERTICAL , ""); + } + SxLib2SignalPINS(); + sortPINS(); + revPINPORT(); + checkPIN(); + + /* SxLib2ALU1OBS(); */ + SxLib2ALUxOBS(ALU2); + SxLib2ALUxOBS(ALU3); + SxLib2ALUxOBS(ALU4); + SxLib2ALUxOBS(ALU5); + SxLib2ALUxOBS(ALU6); + m_RevObs(LV_pMACRO->lOBS); + + + return(LV_pMACRO); +} + + +/* ---------------------------------------------------------------------- + * Function : "lefsavesxlophig()". + */ + +extern void lefsavesxlophfig(apLofig, apPhfig, aFlags) + struct lofig *apLofig; + struct phfig *apPhfig; + long aFlags; +{ + FILE *LEF_FILE; + char LEF_name[1024]; + + + LV_ref_ref = namealloc ("ref_ref"); + LV_ref_con = namealloc ("ref_con"); + + LV_lofig = apLofig; + LV_phfig = apPhfig; + LV_flags = aFlags; + + (void)SxLib2MACRO (); + + + sprintf (LEF_name, "%s.lef", apLofig->NAME); + LEF_FILE = fopen (LEF_name, "w+"); + + fprintMACRO (LEF_FILE, LV_pMACRO); + + fclose (LEF_FILE); +} diff --git a/alliance/src/sea/src/LEF_drive_sxlib.h b/alliance/src/sea/src/LEF_drive_sxlib.h new file mode 100644 index 00000000..e3f863e3 --- /dev/null +++ b/alliance/src/sea/src/LEF_drive_sxlib.h @@ -0,0 +1,35 @@ +/* + * $Id: LEF_drive_sxlib.h,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Header : "./LEF_drive_sxlib.h" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# ifndef __LEF_drive_sxlib__ +# define __LEF_drive_sxlib__ + + /* SxLib to LEF conversion options. */ +# define F_ALLOW_OFFGRID 0x00000001 +# define F_NO_POWER_GEOM 0x00000002 +# define F_POWER_ABUTMENT 0x00000004 +# define F_POWER_FEEDTHRU 0x00000008 + + + extern void lefsavesxlophfig (struct lofig *apLofig, + struct phfig *apPhfig, + long aFlags); + + +# endif diff --git a/alliance/src/sea/src/MAC_drive.c b/alliance/src/sea/src/MAC_drive.c new file mode 100644 index 00000000..5e39a667 --- /dev/null +++ b/alliance/src/sea/src/MAC_drive.c @@ -0,0 +1,319 @@ +/* + * $Id: MAC_drive.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./MAC_drive.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" +# include "MAC_drive.h" + + +# define SIZE_SNAME 1024 + + +/* ------------------------------------------------------------------ + * Local variables. + */ + + static FILE *MAC_FILE; + + +/* ------------------------------------------------------------------ + * Local functions. + */ + + static void fillTie __FP((struct phfig *apPhfig)); + + +/* + * /----------------------------------------------------------------\ + * | Functions Definitions | + * \----------------------------------------------------------------/ + */ + +/* ------------------------------------------------------------------ + * Function : "fillTie()". + */ + +static void fillTie(apPhfig) + struct phfig *apPhfig; +{ + /* Fill with spare space with "tie_x0", two pitchs wide with polarization + * contacts for P bulk and N bulk. + */ + fprintf (MAC_FILE, " SROUTE ADDCELL\n"); + fprintf (MAC_FILE, " MODEL tie_x0 PREFIX tiex0\n"); + fprintf (MAC_FILE, " SPIN vdd NET vdd\n"); + fprintf (MAC_FILE, " SPIN vss NET vss\n"); + fprintf (MAC_FILE, " AREA (%ld %ld) (%ld %ld)\n", + MBK2DEF_length (apPhfig->XAB1), + MBK2DEF_length (apPhfig->YAB1), + MBK2DEF_length (apPhfig->XAB2), + MBK2DEF_length (apPhfig->YAB2)); + fprintf (MAC_FILE, " ;\n\n"); + + /* Fill with the one pitch cell "rowend_x0". */ + fprintf (MAC_FILE, " SROUTE ADDCELL\n"); + fprintf (MAC_FILE, " MODEL rowend_x0 PREFIX rowendx0\n"); + fprintf (MAC_FILE, " SPIN vdd NET vdd\n"); + fprintf (MAC_FILE, " SPIN vss NET vss\n"); + fprintf (MAC_FILE, " AREA (%ld %ld) (%ld %ld)\n", + MBK2DEF_length (apPhfig->XAB1), + MBK2DEF_length (apPhfig->YAB1), + MBK2DEF_length (apPhfig->XAB2), + MBK2DEF_length (apPhfig->YAB2)); + fprintf (MAC_FILE, " ;\n\n"); +} + +/* ------------------------------------------------------------------ + * Function : "macPlace()". + */ + +extern void macPlace(apPhfig, apLofig, macName, aPower, aFlags) + struct phfig *apPhfig; + struct lofig *apLofig; + char *macName; + long aPower; + long aFlags; +{ + MAC_FILE = mbkfopen (macName, "mac", "w+"); + if (!MAC_FILE) { + errMBK (NULL); + eprintf ("Can't open SE mac file \"%s.mac\".", macName); + EXIT (1); + } + + + /* Set a nice viewport. */ + fprintf (MAC_FILE, " WINDOW FIT ;\n\n"); + + + if (aFlags & F_MAC_FIXED_PINS) { + fprintf (MAC_FILE, " IOPLACE\n"); + if (aFlags & F_MAC_IOC) { + fprintf (MAC_FILE, " FILENAME %s.ioc\n", apLofig->NAME); + } + fprintf (MAC_FILE, " TOPBOTTOMLAYER L_ALU2\n"); + fprintf (MAC_FILE, " RIGHTLEFTLAYER L_ALU2\n"); + fprintf (MAC_FILE, " ;\n\n"); + } + + + /* Power stripes made of "powmid_x0". */ + if (aPower > 0) { + fprintf (MAC_FILE, " SROUTE ADDCELL\n"); + fprintf (MAC_FILE, " MODEL powmid_x0 PREFIX powmidx0\n"); + fprintf (MAC_FILE, " SPIN vdd NET vdd\n"); + fprintf (MAC_FILE, " SPIN vss NET vss\n"); + fprintf (MAC_FILE, " AREA (%ld %ld) (%ld %ld)\n", + MBK2DEF_length (apPhfig->XAB1), + MBK2DEF_length (apPhfig->YAB1), + MBK2DEF_length (apPhfig->XAB2), + MBK2DEF_length (apPhfig->YAB2)); + fprintf (MAC_FILE, " XNUM %ld\n", aPower); + fprintf (MAC_FILE, " ;\n\n"); + } + + + /* Placement itself. */ + fprintf (MAC_FILE, " SET VARIABLE Qplace.Place.Pin \"concurrent\" ;\n" ); + fprintf (MAC_FILE, " QPLACE NOCONFIG ;\n\n"); + + + /* Fill with tie cells. */ + if (aFlags & F_MAC_FILL_TIE) fillTie (apPhfig); + + + /* Save the placement file. */ + fprintf (MAC_FILE, " OUTPUT DEF FILENAME %s_p.def ;\n\n", apLofig->NAME); + + + /* Fast QUIT : do not save the internal SE data-base. */ + fprintf (MAC_FILE, " FQUIT ;\n"); + + + fclose (MAC_FILE); +} + + +/* ------------------------------------------------------------------ + * Function : "macRoute()". + */ + +extern void macRoute(apPhfig, apLofig, macName, aPower, aFlags) + struct phfig *apPhfig; + struct lofig *apLofig; + char *macName; + long aPower; + long aFlags; +{ + struct eLoseg_s *pLoseg; + struct losig *pLosig; + struct phseg *pPhseg; + long isRouted, isFirst /*, dx */; + char *sigName; + char defSigName[SIZE_SNAME]; + + + MAC_FILE = mbkfopen (macName, "mac", "w+"); + if (!MAC_FILE) { + errMBK (NULL); + eprintf ("Can't open SE mac file \"%s.mac\".", macName); + EXIT (1); + } + + + /* Set a nice viewport. */ + fprintf (MAC_FILE, " WINDOW FIT ;\n\n"); + + + /* Fill with tie cells. */ + if (aFlags & F_MAC_FILL_TIE) fillTie (apPhfig); + + + if (aFlags & F_MAC_FIXED_PINS) { + fprintf (MAC_FILE, " IOPLACE\n"); + if (aFlags & F_MAC_IOC) { + fprintf (MAC_FILE, " FILENAME %s.ioc\n", apLofig->NAME); + } + fprintf (MAC_FILE, " TOPBOTTOMLAYER L_ALU2\n"); + fprintf (MAC_FILE, " RIGHTLEFTLAYER L_ALU2\n"); + fprintf (MAC_FILE, " ;\n\n"); + } + + + if (! (aFlags & F_MAC_NO_POWER)) { + /* Special routing : ALU1 horizontal stripes. */ + fprintf (MAC_FILE, " SROUTE FOLLOWPINS\n"); + fprintf (MAC_FILE, " NET vdd NET vss\n"); + fprintf (MAC_FILE, " LAYER L_ALU1 WIDTH 600 FILL DIRECTION HORIZONTAL\n"); + fprintf (MAC_FILE, " AREA (%ld %ld) (%ld %ld)\n", + MBK2DEF_length (apPhfig->XAB1), + MBK2DEF_length (apPhfig->YAB1), + MBK2DEF_length (apPhfig->XAB2), + MBK2DEF_length (apPhfig->YAB2)); + fprintf (MAC_FILE, " ;\n\n"); + + + /* Special routing : ALU3 vertical stripes. */ + if (findphmodel (apPhfig, namealloc ("powmid_x0"))) { + fprintf (MAC_FILE, " SROUTE FOLLOWPINS\n"); + fprintf (MAC_FILE, " NET vdd NET vss\n"); + fprintf (MAC_FILE, " LAYER L_ALU3 WIDTH 1200 FILL DIRECTION VERTICAL\n"); + fprintf (MAC_FILE, " AREA (%ld %ld) (%ld %ld)\n", + MBK2DEF_length (apPhfig->XAB1), + MBK2DEF_length (apPhfig->YAB1), + MBK2DEF_length (apPhfig->XAB2), + MBK2DEF_length (apPhfig->YAB2)); + fprintf (MAC_FILE, " ;\n\n"); + } + } + + + /* Global routing of regular nets. */ + fprintf (MAC_FILE, " GROUTE ;\n\n"); + + + /* Final routing of regular nets. */ + fprintf (MAC_FILE, " FROUTE "); + + isFirst = TRUE; + + for(pLosig = apLofig->LOSIG; + pLosig != (losig_list*)NULL; pLosig = pLosig->NEXT) { + sigName = getsigname (pLosig); + + if (isvdd (sigName) || isvss (sigName)) continue; + + if (apPhfig) { + isRouted = FALSE; + pLoseg = getloseglist (apPhfig, getsigname (pLosig)); + + for (; pLoseg != NULL; pLoseg = pLoseg->next) { + if (pLoseg->type == LOSEG_SEG) { + pPhseg = (struct phseg*)(pLoseg->MBKobj); + + /* Is this segment touching the AB. */ + /*if ( ( (pPhseg->X1 == apPhfig->XAB1) + * && (pPhseg->Y1 > apPhfig->YAB1) + * && (pPhseg->Y1 < apPhfig->YAB2)) + * || ( (pPhseg->X2 == apPhfig->XAB1) + * && (pPhseg->Y1 > apPhfig->YAB1) + * && (pPhseg->Y1 < apPhfig->YAB2)) + * || ( (pPhseg->X1 == apPhfig->XAB2) + * && (pPhseg->Y1 > apPhfig->YAB1) + * && (pPhseg->Y1 < apPhfig->YAB2)) + * || ( (pPhseg->X2 == apPhfig->XAB2) + * && (pPhseg->Y1 > apPhfig->YAB1) + * && (pPhseg->Y1 < apPhfig->YAB2)) + * + * || ( (pPhseg->Y1 == apPhfig->YAB1) + * && (pPhseg->X1 > apPhfig->XAB1) + * && (pPhseg->X1 < apPhfig->XAB2)) + * || ( (pPhseg->Y2 == apPhfig->YAB1) + * && (pPhseg->X1 > apPhfig->XAB1) + * && (pPhseg->X1 < apPhfig->XAB2)) + * || ( (pPhseg->Y1 == apPhfig->YAB2) + * && (pPhseg->X1 > apPhfig->XAB1) + * && (pPhseg->X1 < apPhfig->XAB2)) + * || ( (pPhseg->Y2 == apPhfig->YAB2) + * && (pPhseg->X1 > apPhfig->XAB1) + * && (pPhseg->X1 < apPhfig->XAB2))) { + * continue; + */ + /* + * dx = 0; + * + * switch (pPhseg->TYPE) { + * case UP: + * case DOWN: dx = pPhseg->Y2 - pPhseg->Y1; break; + * case LEFT: + * case RIGHT: dx = pPhseg->X2 - pPhseg->X1; break; + * } + * + * if (dx == MBKSCALE (5)) continue; + */ + /*} */ + + isRouted = TRUE; break; + } + } + + if (isRouted) { + if (!isFirst) { + fprintf (MAC_FILE, " "); + } + + isFirst = FALSE; + + fprintf (MAC_FILE, "NONETS \"%s\"\n", + MBK2DEF_name (defSigName, sigName)); + } + } + } + fprintf (MAC_FILE, " ;\n\n"); + + + /* Save the routed file. */ + fprintf (MAC_FILE, " OUTPUT DEF FILENAME %s_r.def ;\n\n", apLofig->NAME); + + + /* Fast QUIT : do not save the internal SE data-base. */ + fprintf (MAC_FILE, " FQUIT ;\n"); + + + fclose (MAC_FILE); +} diff --git a/alliance/src/sea/src/MAC_drive.h b/alliance/src/sea/src/MAC_drive.h new file mode 100644 index 00000000..b6bed34a --- /dev/null +++ b/alliance/src/sea/src/MAC_drive.h @@ -0,0 +1,42 @@ +/* + * $Id: MAC_drive.h,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Header : "./MAC_drive.h" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# ifndef __MAC_drive__ +# define __MAC_drive__ + + +# define F_MAC_IOC 0x00000001 +# define F_MAC_NO_POWER 0x00000002 +# define F_MAC_FIXED_PINS 0x00000004 +# define F_MAC_FILL_TIE 0x00000008 + + + extern void macPlace __FP((struct phfig *apPhfig, + struct lofig *apLofig, + char *macName, + long aPower, + long aFlags)); + extern void macRoute __FP((struct phfig *apPhfig, + struct lofig *apLofig, + char *macName, + long aPower, + long aFlags)); + + +# endif diff --git a/alliance/src/sea/src/Makefile.am b/alliance/src/sea/src/Makefile.am new file mode 100644 index 00000000..8c31c950 --- /dev/null +++ b/alliance/src/sea/src/Makefile.am @@ -0,0 +1,107 @@ +## Process this file with automake to produce Makefile.in + +AM_YFLAGS = -d -v -p DEF_grammar +AM_LFLAGS = -s -f -8 -pp -PDEF_grammar -olex.yy.c + +AM_CFLAGS = @ALLIANCE_CFLAGS@ + +bin_PROGRAMS = a2def def2a sxlib2lef +bin_SCRIPTS = sea seroute seplace a2lef + +a2def_LDADD = @ALLIANCE_LIBS@ \ + $(top_builddir)/src/libUtil.a \ + -lMpu -lMlu \ + -lMcl -lMcp \ + -lMal -lMap \ + -lMsl \ + -lMel -lMgl \ + -lMhl \ + -lMvl \ + -lMmg \ + -lMlo \ + -lMph -lMut \ + -lRcn \ + -lAut + +def2a_LDADD = @ALLIANCE_LIBS@ \ + $(top_builddir)/src/libUtil.a \ + -lMpu -lMlu \ + -lMcl -lMcp \ + -lMal -lMap \ + -lMsl \ + -lMel -lMgl \ + -lMhl \ + -lMvl \ + -lMmg \ + -lMlo \ + -lMph -lMut \ + -lRcn \ + -lAut + +sxlib2lef_LDADD = @ALLIANCE_LIBS@ \ + $(top_builddir)/src/libUtil.a \ + -lMpu -lMlu \ + -lMcl -lMcp \ + -lMal -lMap \ + -lMsl \ + -lMel -lMgl \ + -lMhl \ + -lMvl \ + -lMmg \ + -lMlo \ + -lMph -lMut \ + -lRcn \ + -lAut + +noinst_LIBRARIES = libUtil.a + +libUtil_a_SOURCES = util_Floorplan.c \ + util_Inter.c \ + util_LEFDEF.c \ + util_MBK.c \ + util_Power.c \ + util_RTU.c \ + util_Sys.c \ + util_Defs.h \ + GNU_Defs.h + +a2def_SOURCES = DEF_drive.c \ + DEF_drive.h \ + MAC_drive.c \ + MAC_drive.h \ + a2DEF.c + +def2a_SOURCES = DEF_actions.c \ + DEF_actions.h \ + DEF_grammar.h \ + DEF_grammar_yacc.y \ + DEF_grammar_lex.l \ + DEF2a.c + +sxlib2lef_SOURCES = LEF_drive.h \ + LEF_drive.c \ + LEF_drive_sxlib.c \ + LEF_drive_sxlib.h \ + sxlib2LEF.c + +sea: $(srcdir)/sea.sh + cp $< $@ + chmod a+x $@ + +seplace: $(srcdir)/seplace.sh + cp $< $@ + chmod a+x $@ + +seroute: $(srcdir)/seroute.sh + cp $< $@ + chmod a+x $@ + +a2lef: $(srcdir)/a2lef.sh + cp $< $@ + chmod a+x $@ + +EXTRA_DIST = debug.c debugon.h debugoff.h + +CLEANFILES =DEF_grammar_lex.c DEF_grammar_yacc.c \ + y.output DEF_grammar_yacc.h \ + seplace seroute sea a2lef diff --git a/alliance/src/sea/src/a2DEF.c b/alliance/src/sea/src/a2DEF.c new file mode 100644 index 00000000..35bb8578 --- /dev/null +++ b/alliance/src/sea/src/a2DEF.c @@ -0,0 +1,639 @@ +/* + * $Id: a2DEF.c,v 1.1 2002/04/25 16:16:19 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./a2DEF.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" +# include "DEF_drive.h" +# include "MAC_drive.h" + + +/* ------------------------------------------------------------------ + * Local constants. + */ + +# define A_PHFIG 0x00000001 /* 1 */ +# define A_FIXED_PINS 0x00000002 /* 2 */ +# define A_PAD 0x00000004 /* 4 */ +# define A_LAYERS_3 0x00000008 /* 8 */ +# define A_LAYERS_4 0x00000010 /* 8 */ +# define A_LAYERS_6 0x00000020 /* 16 */ +# define A_FLOORPLAN 0x00000040 /* 32 */ +# define A_MARGIN 0x00000080 /* 64 */ +# define A_ROW_NUMBER 0x00000100 /* 128 */ +# define A_X_SIZE 0x00000200 /* 256 */ +# define A_Y_SIZE 0x00000400 /* 512 */ +# define A_ASPECT_RATIO 0x00000800 /* 1024 */ +# define A_POWER 0x00001000 /* 2048 */ +# define A_EXPAND_PLACE 0x00002000 /* 4096 */ +# define A_EXPAND_ROUTE 0x00004000 /* 4096 */ +# define A_MAC_PLACE 0x00008000 /* 8192 */ +# define A_MAC_ROUTE 0x00010000 /* 16384 */ +# define A_MAC_IOC 0x00020000 /* 16384 */ +# define A_MAC_NO_POWER 0x00040000 /* 16384 */ +# define A_MAC_FILL_TIE 0x00080000 /* 16384 */ +# define A_TRUST_ORIENT 0x00100000 /* 16384 */ + + +/* ---------------------------------------------------------------------- + * Local functions. + */ + +static void printHelp __FP((void)); + + +/* + * /--------------------------------------------------------------------\ + * | Functions Definitions | + * \--------------------------------------------------------------------/ + */ + +/* ---------------------------------------------------------------------- + * Function : "printHelp()". + */ + +static void printHelp() +{ + printf (" o Usage := \"a2def [-h] [-v] [-V]\n"); + printf (" [-b] [-c] [-P] [-3] [-6] [-e] [-E]\n"); + printf (" [--mac-place=]\n"); + printf (" [--mac-route=]\n"); + printf (" [--ioc] [-n] [-t]\n"); + printf (" [-F [--margin= |\n"); + printf (" --row-number= |\n"); + printf (" --x-size= |\n"); + printf (" --y-size= |\n"); + printf (" --aspect-ratio=|\n"); + printf (" --power= ]]\n"); + printf (" [--place=]\n"); + printf (" []\"\n\n"); + printf (" o Options :\n"); + printf (" [-v] := Be verbose.\n"); + printf (" [-V] := Be very verbose.\n"); + printf (" [-h] := Print this message.\n"); + printf (" [-b] := Do not put terminals on the abutment box.\n"); + printf (" [-c] := Put terminals on the abutment box.\n"); + printf (" [-P] := The design have pads.\n"); + printf (" [-3] := Uses only 3 levels of metal.\n"); + printf (" [-6] := Uses all 6 levels of metal.\n"); + printf (" [-e] := Expand AB of the physical figure (place).\n"); + printf (" [-E] := Expand AB of the physical figure (route).\n"); + printf (" [-F] := Generate a floorplan.\n"); + printf (" [-n] := Do not route power supplies (in .mac).\n"); + printf (" [-T] := Trust MBK instance orientations.\n"); + printf (" [-t] := Fill the remaining space with tie (in .mac).\n"); + printf (" [--ioc] := Terminal placement file, used by the mac\n"); + printf (" generator.\n"); + printf (" [--mac-place=] :=\n"); + printf (" Generate a Silicon Ensemble script (.mac)\n"); + printf (" for the placement step.\n"); + printf (" [--mac-route=] :=\n"); + printf (" Generate a Silicon Ensemble script (.mac)\n"); + printf (" for the routing step.\n"); + printf (" [--margin=] :=\n"); + printf (" Set the free area in percentage of the\n"); + printf (" cell area. The resulting area will be\n"); + printf (" equal to CELL_AREA * (1 + /100).\n"); + printf (" Default value 10.\n"); + printf (" [--row-number=] :=\n"); + printf (" Set the preferred number of rows of the\n"); + printf (" design to . The width is computed.\n"); + printf (" [--x-size=] :=\n"); + printf (" Set the preferred width of the design to\n"); + printf (" . is rounded to the pitch\n"); + printf (" (currently 5 lambdas). The height is\n"); + printf (" computed.\n"); + printf (" [--y-size=] :=\n"); + printf (" Set the preferred height of the design to\n"); + printf (" . is rounded to the pitch\n"); + printf (" (currently 50 lambdas). The width is\n"); + printf (" computed.\n"); + printf (" [--aspect-ratio=] :=\n"); + printf (" Set the preferred form factor of the design\n"); + printf (" to .\n"); + printf (" [--power=] :=\n"); + printf (" Set the number of vertical power rail to \n"); + printf (" (default : 1).\n"); + printf (" [--place=] :=\n"); + printf (" The Design is preplaced/prerouted.\n"); + printf (" := The input netlist (mandatory).\n"); + printf (" := The output DEF file.\n"); + printf ("\n" ); +} + + +/* ---------------------------------------------------------------------- + * Function : "main()". + */ + +extern int main(argc, argv) + int argc; + char *argv[]; +{ + struct lofig *pLofig; + struct phfig *pPhfig; + struct loins *pLoins; + char *netlistName, *layoutName, *defName; + int argC, i, optCount; + long VL, argFlags, defFlags, floFlags, macFlags; + long margin, xSize, ySize, power; + double formFactor; + char macPlaceName[1024], macRouteName[1024]; + + + /* Read MBK environment. */ + mbkenv (); + autenv (); + + /* Initialise the "util" module. */ + util_init (C_VerboseLevel2, F_DUMPCORE, "a2DEF"); + + + optCount = 0; + argC = argc; + pPhfig = NULL; + + /* Default options. */ + layoutName = NULL; + defName = NULL; + VL = C_VerboseLevel0; + defFlags = F_LAYERS_6; + floFlags = F_FLOOR_ASPECT_RATIO; + argFlags = 0L; + macFlags = 0L; + margin = 10L; + xSize = 0L; + ySize = 0L; + formFactor = 1.0; + power = 1; + + /* Read the options. */ + for(i = 1; i < argc; i++) { + /* + * fflush (stdout); + * fprintf (stderr, "argFlags := %ld (%s)\n", argFlags, argv[i]); + */ + if (!strcmp (argv[i], "-h")) { printHelp (); exit (0); } + if (!strcmp (argv[i], "-v")) { VL = C_VerboseLevel1; continue; } + if (!strcmp (argv[i], "-V")) { VL = C_VerboseLevel2; continue; } + if (!strcmp (argv[i], "-e")) { argFlags |= A_EXPAND_PLACE; + defFlags |= F_EXPAND_PLACE; + continue; } + if (!strcmp (argv[i], "-E")) { argFlags |= A_EXPAND_ROUTE; + defFlags |= F_EXPAND_ROUTE; + continue; } + + /* Short options. */ + if (!strcmp (argv[i], "-c")) { + argFlags |= A_FIXED_PINS; + defFlags |= F_FIXED_PINS; + /*macFlags |= F_MAC_FIXED_PINS;*/ + continue; + } + + if (!strcmp (argv[i], "-b")) { + argFlags &= ~A_FIXED_PINS; + defFlags &= ~F_FIXED_PINS; + continue; + } + + if (!strcmp (argv[i], "-p")) { + continue; + } + if (!strncmp (argv[i], "--place=", 8)) { + argFlags |= A_PHFIG; + defFlags |= F_PHFIG; + power = 0; + layoutName = namealloc (argv[i] + 8); + continue; + } + + if (!strcmp (argv[i], "-P")) { + argFlags |= A_PAD; + argFlags &= ~A_FIXED_PINS; + defFlags |= F_PAD; + defFlags &= ~F_FIXED_PINS; + continue; + } + + if (!strcmp (argv[i], "-3")) { + argFlags |= A_LAYERS_3; + argFlags &= ~A_LAYERS_4; + argFlags &= ~A_LAYERS_6; + defFlags |= F_LAYERS_3; + defFlags &= ~F_LAYERS_4; + defFlags &= ~F_LAYERS_6; + floFlags |= F_FLOOR_LAYERS_3; + floFlags &= ~F_FLOOR_LAYERS_4; + floFlags &= ~F_FLOOR_LAYERS_6; + continue; + } + + if (!strcmp (argv[i], "-4")) { + argFlags |= A_LAYERS_4; + argFlags &= ~A_LAYERS_3; + argFlags &= ~A_LAYERS_6; + defFlags |= F_LAYERS_4; + defFlags &= ~F_LAYERS_3; + defFlags &= ~F_LAYERS_6; + floFlags |= F_FLOOR_LAYERS_4; + floFlags &= ~F_FLOOR_LAYERS_3; + floFlags &= ~F_FLOOR_LAYERS_6; + continue; + } + + if (!strcmp (argv[i], "-6")) { + argFlags |= A_LAYERS_6; + argFlags &= ~A_LAYERS_3; + defFlags |= F_LAYERS_6; + defFlags &= ~F_LAYERS_3; + floFlags |= F_FLOOR_LAYERS_6; + floFlags &= ~F_FLOOR_LAYERS_3; + continue; + } + + if (!strcmp (argv[i], "--ioc")) { + argFlags |= A_MAC_IOC; + macFlags |= F_MAC_IOC; + continue; + } + + if (!strcmp (argv[i], "-n")) { + argFlags |= A_MAC_NO_POWER; + macFlags |= F_MAC_NO_POWER; + continue; + } + + if (!strcmp (argv[i], "-t")) { + argFlags |= A_MAC_FILL_TIE; + macFlags |= F_MAC_FILL_TIE; + continue; + } + + if (!strcmp (argv[i], "-T")) { + argFlags |= A_TRUST_ORIENT; + defFlags |= F_TRUST_ORIENT; + continue; + } + + if (!strncmp (argv[i], "--mac-place=", 12)) { + argFlags |= A_MAC_PLACE; + strcpy (macPlaceName, argv[i] + 12); + continue; + } + + if (!strncmp (argv[i], "--mac-route=", 12)) { + argFlags |= A_MAC_ROUTE; + strcpy (macRouteName, argv[i] + 12); + continue; + } + + + if (!strcmp (argv[i], "-F")) { argFlags |= A_FLOORPLAN; continue; } + + /* Long options : associated with floorplan. */ + if (!strncmp (argv[i], "--margin=", 9)) { + argFlags |= A_MARGIN; + if (1 != sscanf (argv[i] + 9, "%ld", &margin)) { + eprinth (NULL); + eprintf ("Invalid value.\n"); + printHelp (); + exit (2); + } + if (margin < 0) { + eprinth (NULL); + eprintf ("Negative value (%ld).\n", margin); + printHelp (); + exit (2); + } + continue; + } + + if (!strncmp (argv[i], "--row-number=", 13)) { + optCount += 1; + argFlags |= A_ROW_NUMBER; + floFlags |= F_FLOOR_Y_SIZE; + floFlags &= ~F_FLOOR_ASPECT_RATIO; + if (1 != sscanf (argv[i] + 13, "%ld", &ySize)) { + eprinth (NULL); + eprintf ("Invalid value.\n\n"); + printHelp (); + exit (2); + } + if (ySize <= 0) { + eprinth (NULL); + eprintf ("Negative or null value (%ld).\n", margin); + printHelp (); + exit (2); + } + continue; + } + + if (!strncmp (argv[i], "--y-size=", 9)) { + optCount += 1; + argFlags |= A_Y_SIZE; + floFlags |= F_FLOOR_Y_SIZE; + floFlags &= ~F_FLOOR_ASPECT_RATIO; + if (1 != sscanf (argv[i] + 9, "%ld", &ySize)) { + eprinth (NULL); + eprintf ("Invalid value.\n\n"); + printHelp (); + exit (2); + } + if (ySize <= 0) { + eprinth (NULL); + eprintf ("Negative or null value (%ld).\n", ySize); + printHelp (); + exit (2); + } + ySize /= Y_SLICE; + continue; + } + + if (!strncmp (argv[i], "--x-size=", 9)) { + optCount += 1; + argFlags |= A_X_SIZE; + floFlags |= F_FLOOR_X_SIZE; + floFlags &= ~F_FLOOR_ASPECT_RATIO; + if (1 != sscanf (argv[i] + 9, "%ld", &xSize)) { + eprinth (NULL); + eprintf ("Invalid value.\n\n"); + printHelp (); + exit (2); + } + if (xSize <= 0) { + eprinth (NULL); + eprintf ("Negative or null value (%ld).\n", xSize); + printHelp (); + exit (2); + } + xSize /= X_GRID; + continue; + } + + if (!strncmp (argv[i], "--aspect-ratio=", 15)) { + optCount += 1; + argFlags |= A_ASPECT_RATIO; + floFlags |= F_FLOOR_ASPECT_RATIO; + if (1 != sscanf (argv[i] + 15, "%lf", &formFactor)) { + eprinth (NULL); + eprintf ("Invalid value.\n\n"); + printHelp (); + exit (2); + } + if (formFactor <= 0.0) { + eprinth (NULL); + eprintf ("Negative or null value (%f).\n", formFactor); + printHelp (); + exit (2); + } + continue; + } + + if (!strncmp (argv[i], "--power=", 8)) { + argFlags |= A_POWER; + if (1 != sscanf (argv[i] + 8, "%ld", &power)) { + eprinth (NULL); + eprintf ("Invalid value.\n\n"); + printHelp (); + exit (2); + } + if (power < 0) { + eprinth (NULL); + eprintf ("Negative value (%ld).\n", power); + printHelp (); + exit (2); + } + continue; + } + + if ((argC - i) > 2) { + eprinth (NULL); + eprintf ("Unknown argument \"%s\"\n\n", argv[argC - 1]); + printHelp (); + exit (1); + } + else + break; + } + + if ((argC - i) < 1) { + eprinth (NULL); + eprintf ("Missing netlist name .\n\n"); + printHelp (); + exit (1); + } else { + netlistName = namealloc (argv[i]); + + if ((argC - i) == 2) + defName = namealloc (argv[i + 1]); + else + defName = netlistName; + } + + + if (argFlags & A_FLOORPLAN) { + if (argFlags & A_PHFIG) { + eprinth (NULL); + eprintf ("\n Options -F and -p are mutually exclusive : either you"); + eprintf (" want to make\n a floorplan or you supply a placement file."); + eprintf ("\n"); + exit (1); + } + + if (optCount > 1) { + eprinth (NULL); + eprintf ("\n Options --row-number, --x-size, --y-size and"); + eprintf (" --aspect-ratio\n"); + eprintf ( " are mutually exclusive.\n)"); + exit (1); + } + + if (!optCount) argFlags |= A_ASPECT_RATIO; + } else { + if (argFlags & A_MARGIN) { + wprinth (NULL); + wprintf (" ignored --margin argument, must be used with -F\n"); + } + + if (argFlags & A_X_SIZE) { + wprinth (NULL); + wprintf (" ignored --x-size argument, must be used with -F\n"); + } + + if (argFlags & A_Y_SIZE) { + wprinth (NULL); + wprintf (" ignored --y-size argument, must be used with -F\n"); + } + + if (argFlags & A_ASPECT_RATIO) { + wprinth (NULL); + wprintf (" ignored --aspect-ratio argument, must be used with -F\n"); + } + + if ((argFlags & A_EXPAND_PLACE) && !(argFlags & A_PHFIG)) { + wprinth (NULL); + wprintf (" ignored -e argument, no physical layout.\n"); + } + + if ((argFlags & A_EXPAND_ROUTE) && !(argFlags & A_PHFIG)) { + wprinth (NULL); + wprintf (" ignored -E argument, no physical layout.\n"); + } + } + + + setVL (VL); + + if (VL > C_VerboseLevel0) + alliancebanner( + "a2DEF", "V.RR", "Alliance to DEF converter", + "2000", ALLIANCE_VERSION ); + + printMBKEnv (); + if (argFlags & A_PAD) mprintf1 (" o Forced pad design.\n"); + if (argFlags & A_PHFIG) mprintf1 (" o Preplaced/prerouted design.\n"); + + + mprintf2 (" o Loading \"%s\" (logical).\n", netlistName); + + pLofig = getlofig (netlistName, 'A'); + + if (defFlags & F_PHFIG) { + mprintf2 (" o Loading \"%s\" (physical).\n", layoutName); + pPhfig = getphfig (layoutName, 'A'); + } else + pPhfig = (phfig_list *)NULL; + + + mprintf2 (" o Flattening \"%s\" to the catalog.\n", netlistName); + mprintf2 (" (using MBK_SEPAR := \'%c\' as separator)\n", SEPAR); + if (defFlags & F_PHFIG) + rflattenphfig (pPhfig, YES, YES); + rflattenlofig (pLofig, YES, YES); + + + /* Build a floorplan. */ + if (argFlags & A_FLOORPLAN) { + mprintf2 (" o Making floorplan.\n"); + + pPhfig = makeFloorplan (pLofig, + margin, + xSize, + ySize, + formFactor, + power, + floFlags); + + if (layoutName) pPhfig->NAME = layoutName; + + /*savephfig (pPhfig);*/ + } + + + /* Add ROWS & TRACKS references, if needed. */ + if ((argFlags & A_PHFIG) && (!hasROW (pPhfig))) { + mprintf2 (" o Building default ROWS and TRACKS.\n"); + + buildROWS (pPhfig); + buildTRACKS (pPhfig, defFlags); + } + + + /* Place terminals. */ + mprintf2 (" o Placing terminals.\n"); + /* placeTerms (pLofig, pPhfig); */ + + + if (( (argFlags & A_PHFIG) + || (argFlags & A_FLOORPLAN)) && ( (argFlags & A_EXPAND_PLACE) + || (argFlags & A_EXPAND_ROUTE))) { + mprintf2 (" o Expanding the abutment box.\n"); + + expandFloorplan (pPhfig); + /* savephfig (pPhfig); */ + } + + + /* Try to guess if the design have pads. */ + for (pLoins = pLofig->LOINS; pLoins != NULL; pLoins = pLoins->NEXT) { + if (isPad (pLoins->FIGNAME)) { + defFlags |= F_PAD; + defFlags &= ~F_FIXED_PINS; + + mprintf1 (" o Pads found in this design (%s).\n", + pLoins->FIGNAME); + break; + } + } + + + /* Generate a separate "vdd/vss" for the core and the pads. */ + lofigchain (pLofig); + initSigIndex (pLofig->LOSIG); + if (defFlags & F_PAD) { + splitPowerNet (pLofig, namealloc("vdd")); + splitPowerNet (pLofig, namealloc("vss")); + lofigchain (pLofig); + } + + + /* Build the loseg list. */ + if (defFlags & F_PHFIG) { + phsegchain (pLofig, pPhfig); + } + + + /* Prevent SE to put terminal on power cells. */ + if (pPhfig) protectPowmid (pPhfig); + + + /* Drive the DEF file. */ + defsavelophfig (pLofig, pPhfig, defName, defFlags); + + + /* Drive ".mac" files, if any. */ + if (argFlags & A_MAC_PLACE) { + if (pPhfig) + macPlace (pPhfig, pLofig, macPlaceName, power, macFlags); + else { + eprinth (NULL); + eprintf (" --mac-place= option must be given with"); + eprintf (" [--place] or [-F].\n"); + exit (2); + } + } + if (argFlags & A_MAC_ROUTE) { + if (pPhfig) + macRoute (pPhfig, pLofig, macRouteName, power, macFlags); + else { + eprinth (NULL); + eprintf (" --mac-route= option must be given with"); + eprintf (" [-place] or [-F].\n"); + exit (2); + } + } + + + /* free the loseg list. */ + if (defFlags & F_PHFIG) { + freeloseg (pPhfig); + } + + + exit(0); +} diff --git a/alliance/src/sea/src/a2lef.sh b/alliance/src/sea/src/a2lef.sh new file mode 100644 index 00000000..905468a5 --- /dev/null +++ b/alliance/src/sea/src/a2lef.sh @@ -0,0 +1,427 @@ +#!/bin/sh +# +# $Id: a2lef.sh,v 1.1 2002/04/25 16:16:19 jpc Exp $ +# +# /------------------------------------------------------------------\ +# | | +# | A l l i a n c e C A D S y s t e m | +# | S i l i c o n E n s e m b l e / A l l i a n c e | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : alliance-support@asim.lip6.fr | +# | ================================================================ | +# | Script : "./a2LEF.sh" | +# | **************************************************************** | +# | U p d a t e s | +# | | +# \------------------------------------------------------------------/ +# + + +# -------------------------------------------------------------------- +# Constants definitions. + + VL=0 + techFile="" + lLibDir="" + lefFile="" + sx2lef_args="" + cellName="" + + +# /------------------------------------------------------------------\ +# | | +# | Functions Definitions | +# | | +# \------------------------------------------------------------------/ +# +# -------------------------------------------------------------------- +# Function : "vecho()". + + vecho() + { + if [ $1 -le $VL ]; then + if [ "$2" = "-n" ]; then + printf "$3" + else + echo "$2" + fi + fi + } + + +# -------------------------------------------------------------------- +# Function : "title()". + + title() + { + if [ $VL -ge 1 ]; then + echo "" + alcbanner "a2LEF" "V.RR" "Alliance Library to LEF converter" "2000" + echo "" + fi + } + + +# -------------------------------------------------------------------- +# Function : `print_usage()'. + + print_usage() + { + echo "" + echo "" + echo "Usage: a2LEF.sh [--verbose] [--very-verbose] [--help] \\" + echo " [--allow-offgrid] [--fake-power] \\" + echo " <--techno > \\" + echo " <--library [--library ]> \\" + echo " <--lef > \\" + echo " <--cell >" + echo " a2LEF.sh [-vVhop] <-t > \\" + echo " <-l [-l ]> \\" + echo " <-L > \\" + echo " <-c > " + echo "" + echo "Options:" + echo " o [--help|-h] : print this help." + echo " o [--verbose|-v] : be verbose." + echo " o [--very-verbose|-V] : be very verbose :-)." + echo " o [--allow-offgrid|-o] : allow terminals to be offgrid." + echo " o [--fake-power|-p] : do not attempt to generate" + echo " PORT geometries for power pins." + echo " o <--techno|-t > : location of the LEF techno header." + echo " o <--library|-l > : Alliance library directory." + echo " o <--lef|-L > : output LEF file." + echo " o <--cell|-c > : process a single (macro) cell." + echo "" + echo "" + } + + +# -------------------------------------------------------------------- +# Function : `setTechno()'. + + setTechno() + { + aTechFile="$1" + aLEF="$2" + + rm -f $aLEF > /dev/null 2>&1 + cp $aTechFile $aLEF + } + + +# -------------------------------------------------------------------- +# Function : `buildLib()'. + + buildLib() + { + aLibDir="$1" + aLEF="$2" + + if [ ! -d $aLibDir ]; then + echo "a2LEF:error: Library \"$aLibDir\" doesn't exist." + exit 1 + fi + + + MBK_CATA_LIB="$aLibDir"; export MBK_CATA_LIB + + + lCellAp=`(cd $aLibDir; \ls *.vbe)` + + if [ "$lCellAp" = "" ]; then + echo "a2LEF:error: Library \"$aLibDir\" is empty." + exit 1 + fi + + + libName="`echo $aLibDir | sed 's,.*/,,'`" + vecho 1 "" + vecho 1 " o Processing library \"$libName\"." + + + success="$libName.success" + failed="$libName.failed" + log="$libName.log" + failedNB=0 + successNB=0 + + rm -f $success $failed $log > /dev/null 2>&1 + + for cellAp in $lCellAp; do + + cell=`echo $cellAp | sed 's,\.vbe$,,'` + vecho 2 -n " - \"$cell\"... " + + case $cell in + *_sp) pxlib2lef -V $cell >> $log 2>&1; RV=$?;; + *) sxlib2lef -V $sx2lef_args $cell >> $log 2>&1; RV=$?;; + esac + if [ $RV -ne 0 ]; then + + failedNB=`expr $failedNB + 1` + echo "$cell" >> $failed + + vecho 2 "KO." + + else + + echo "" >> $aLEF + cat $cell.lef >> $aLEF + rm -f $cell.lef + + successNB=`expr $successNB + 1` + echo "$cell" >> $success + + vecho 2 "OK." + + fi + + done + + + vecho 1 " o $successNB successful cells." + + + if [ $failedNB -gt 0 ]; then + + echo "" + echo "a2LEF:error:" + echo " $failedNB failed cells in library \"$libName\"." + echo " Please read \"$log\" for detailed explanations." + exit 1 + + fi + } + + +# -------------------------------------------------------------------- +# Function : `closeLib()'. + + closeLib() + { + aLEF="$1" + + echo "" >> $aLEF + echo "END LIBRARY" >> $aLEF + } + + +# /------------------------------------------------------------------\ +# | | +# | Main Part of the Shell Script | +# | | +# \------------------------------------------------------------------/ +# +# -------------------------------------------------------------------- +# Process the command line. + + while [ $# -gt 0 ]; do + + case $1 in + + --help) print_usage; exit 0;; + --verbose) VL=1;; + --very-verbose) VL=2;; + --allow-offgrid) sx2lef_args="$sx2lef_args -o";; + --fake-power) sx2lef_args="$sx2lef_args -p";; + + --techno) + if [ $# -ge 2 ]; then + techFile="$2" + shift + else + echo "a2LEF.sh:error: Missing argument." + print_usage; exit 1 + fi;; + + --library) + if [ $# -ge 2 ]; then + lLibDir="$lLibDir $2" + shift + else + echo "a2LEF.sh:error: Missing argument." + print_usage; exit 1 + fi + if [ ! -z "$cellName" ]; then + echo -n "a2LEF.sh:error: --library and --cell options are" + echo " mutually exclusive." + print_usage; exit 1 + fi;; + + --lef) + if [ $# -ge 2 ]; then + lefFile="$2" + shift + else + echo "a2LEF.sh:error: Missing argument." + print_usage; exit 1 + fi;; + + --cell) + if [ $# -ge 2 ]; then + cellName="$2" + shift + else + echo "a2LEF.sh:error: Missing argument." + print_usage; exit 1 + fi + if [ ! -z "$lLibDir" ]; then + echo -n "a2LEF.sh:error: --library and --cell options are" + echo " mutually exclusive." + print_usage; exit 1 + fi;; + + --*) echo "a2LEF.sh:error: Invalid argument \`$1'." + print_usage; exit 1;; + + -*) lSwitch="$1"; NB=2; CH=`echo $lSwitch | cut -c$NB` + + while [ "$CH" != "" ]; do + + case $CH in + + h) print_usage; exit 0;; + v) VL=1;; + V) VL=2;; + o) sx2lef_args="$sx2lef_args -o";; + p) sx2lef_args="$sx2lef_args -p";; + + t) if [ $# -ge 2 ]; then + techFile="$2" + shift + else + echo "a2LEF.sh:error: Missing argument." + print_usage; exit 1 + fi;; + + l) if [ $# -ge 2 ]; then + lLibDir="$lLibDir $2" + shift + else + echo "a2LEF.sh:error: Missing argument." + print_usage; exit 1 + fi + if [ ! -z "$cellName" ]; then + echo -n "a2LEF.sh:error: --library and --cell options are" + echo " mutually exclusive." + print_usage; exit 1 + fi;; + + L) + if [ $# -ge 2 ]; then + lefFile="$2" + shift + else + echo "a2LEF.sh:error: Missing argument." + print_usage; exit 1 + fi;; + + c) + if [ $# -ge 2 ]; then + cellName="$2" + shift + else + echo "a2LEF.sh:error: Missing argument." + print_usage; exit 1 + fi + if [ ! -z "$lLibDir" ]; then + echo -n "a2LEF.sh:error: --library and --cell options are" + echo " mutually exclusive." + print_usage; exit 1 + fi;; + + *) echo "a2LEF:error: Invalid option \`$CH'." + print_usage; exit 1;; + + esac + + NB=`expr $NB + 1` + CH=`echo $lSwitch | cut -c$NB` + + done;; + + *) echo "a2LEF:error: Invalid option \`$1'." + print_usage; exit 1;; + + esac + + shift + + done + + + title + + + MBK_IN_PH=ap ; export MBK_IN_PH + MBK_IN_LO=vst ; export MBK_IN_LO + MBK_OUT_PH=ap ; export MBK_OUT_PH + MBK_OUT_LO=vst; export MBK_OUT_LO + + + if [ "$techFile" != "" ]; then + if [ ! -f $techFile ]; then + echo "a2LEF:error: Technological file \"$techFile\" doesn't exist." + exit 1 + fi + setTechno $techFile $lefFile + fi + + + if [ -z "$cellName" ]; then + if [ "$lLibDir" = "" ]; then + echo "a2LEF:error: Missing mandatory argument <--library >." + print_usage; exit 1 + fi + + if [ "$lefFile" = "" ]; then + echo "a2LEF:error: Missing mandatory argument <--lef >." + print_usage; exit 1 + fi + + # ------------------------------------------------------------------ + # Library Generation. + + rm -f $lefFile > /dev/null 2>&1 + + for libDir in $lLibDir; do + buildLib $libDir $lefFile + done + + closeLib $lefFile + else + if [ ! -f ${cellName}.ap ]; then + echo "a2LEF:error: Can't find layout file \"${cellName}.ap\"." + print_usage; exit 1 + fi + + if [ ! -f ${cellName}.vbe -a ! -f ${cellName}.vst ]; then + echo "a2LEF:error: Can't find netlist/behavioral file :" + echo " \"${cellName}.vst or \"${cellName}.vbe\"." + print_usage; exit 1 + fi + + log="$cellName.log" + rm -f $log + + vecho 2 -n " - \"$cellName\"... " + sxlib2lef -V $sx2lef_args $cellName >> $log 2>&1; RV=$? + + if [ $RV -ne 0 ]; then + vecho 2 "KO." + else + vecho 2 "OK." + fi + + closeLib ${cellName}.lef + fi + + + +# -------------------------------------------------------------------- +# That's all Folks. + + vecho 2 "" + vecho 2 "" + exit 0 diff --git a/alliance/src/sea/src/debug.c b/alliance/src/sea/src/debug.c new file mode 100644 index 00000000..f70b9578 --- /dev/null +++ b/alliance/src/sea/src/debug.c @@ -0,0 +1,73 @@ + +/* + * $Id: debug.c,v 1.1 2002/04/25 16:16:19 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./debug.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" + + + + + +/* + * /--------------------------------------------------------------------\ + * | Functions Definitions | + * \--------------------------------------------------------------------/ + */ + +/* ---------------------------------------------------------------------- + * Function : "main()". + */ + +extern int main(argc, argv) + int argc; + char *argv[]; +{ + struct lInter_s *pInter; + + + pInter = NULL; + + /* Add the "B" segments. */ + pInter = addinter (pInter, 1, 3); + pInter = addinter (pInter, 5, 7); + pInter = addinter (pInter, 9, 11); + pInter = addinter (pInter, 13, 15); + pInter = addinter (pInter, 17, 19); +# if 0 +# endif + + /* See if the B segments are OK. */ + printinter (pInter); + + /* Add the "A" interval. */ + pInter = addinter (pInter, 4, 16); +# if 0 + pInter = addinter (pInter, 6, 14); + pInter = addinter (pInter, 2, 6); +# endif + + /* See if the "A" segments has been correctly merged. */ + printinter (pInter); + + + /* Free all intervals. */ + freeinter (pInter); + + exit(0); +} diff --git a/alliance/src/sea/src/debugoff.h b/alliance/src/sea/src/debugoff.h new file mode 100644 index 00000000..bfc6bbd6 --- /dev/null +++ b/alliance/src/sea/src/debugoff.h @@ -0,0 +1,28 @@ +/* + * $Id: debugoff.h,v 1.1 2002/04/25 16:16:19 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | D p G e n | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Header : "./debugoff.h" | + * | ************************************************************** | + * | Compile without debug specific code. | + * | | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# ifdef __DBG__ +# undef __DBG__ +# endif +# ifdef __DBG +# undef __DBG +# endif +# define __DBG(code) diff --git a/alliance/src/sea/src/debugon.h b/alliance/src/sea/src/debugon.h new file mode 100644 index 00000000..15f4eb8b --- /dev/null +++ b/alliance/src/sea/src/debugon.h @@ -0,0 +1,28 @@ +/* + * $Id: debugon.h,v 1.1 2002/04/25 16:16:19 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | D p G e n | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Header : "./debugon.h" | + * | ************************************************************** | + * | Compile with debug specific code. | + * | | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# ifndef __DBG__ +# define __DBG__ +# endif +# ifdef __DBG +# undef __DBG +# endif +# define __DBG(code) code diff --git a/alliance/src/sea/src/sea.sh b/alliance/src/sea/src/sea.sh new file mode 100644 index 00000000..083d008b --- /dev/null +++ b/alliance/src/sea/src/sea.sh @@ -0,0 +1,466 @@ +#!/bin/sh +# +# $Id: sea.sh,v 1.1 2002/04/25 16:16:20 jpc Exp $ +# +# /------------------------------------------------------------------\ +# | | +# | A l l i a n c e C A D S y s t e m | +# | S i l i c o n E n s e m b l e / A l l i a n c e | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : alliance-support@asim.lip6.fr | +# | ================================================================ | +# | Script : "./sea.sh" | +# | **************************************************************** | +# | U p d a t e s | +# | | +# \------------------------------------------------------------------/ +# + + +# -------------------------------------------------------------------- +# Constants definitions. + + VL=0 + script_SE_init="./se_script_init.mac" + script_SE_load="./se_script_load.mac" + + +# /------------------------------------------------------------------\ +# | | +# | Functions Definitions | +# | | +# \------------------------------------------------------------------/ +# +# -------------------------------------------------------------------- +# Function : "vecho()". + + vecho() + { + if [ $1 -le $VL ]; then + if [ "$2" = "-n" ]; then + printf "$3" + else + echo "$2" + fi + fi + } + + +# -------------------------------------------------------------------- +# Function : "title()". + + title() + { + if [ $VL -ge 1 ]; then + echo "" + alcbanner "Sissi" "1.00" "Alliance Silicon Ensemble Front End" "2000" + echo "" + fi + } + + +# -------------------------------------------------------------------- +# Function : `print_usage()'. + + print_usage() + { + echo "" + echo "" + echo "Usage: sea.sh [--verbose] [--very-verbose] [--help] \\" + echo " [--keep-se] [--keep-tmp] [--no-deflib] \\" + echo " [--memory ] [--ansi] [--batch] \\" + echo " [lef_def_file [lef_def_file]] \\" + echo " sea.sh [-vVhkKNb] [-m ] \\" + echo "" + echo "Options:" + echo " o [--help|-h] : print this help." + echo " o [--verbose|-v] : be verbose." + echo " o [--very-verbose|-V] : be very verbose :-)." + echo " o [--batch|-b] : batch mode." + echo " o [--memory|-m ] : uses Mo for memory. Legal" + echo " memory sizes are 12, 24, 36, 48, 60, 72, 84, 96, 108, 120," + echo " 150, 200, 250, 300, 400, 500, 800, 1200, 1600, 1900." + echo " o [--ansi] :" + echo " run in text mode only (do not start the graphic interface)." + echo " o [--keep-se|-K] : keep SE temporary files." + echo " o [--keep-tmp|-k] : keep SEA temporary files." + echo " o [--no-deflib|-N] :" + echo " Do not load defaults technology, libraries and settings" + echo " (i.e. sxlib & cmos_12)." + echo " o [lef_def_file] :" + echo " LEF or DEF file to load. The files should be given with" + echo " their extention (.lef or .def)." + echo "" + echo "" + } + + +# -------------------------------------------------------------------- +# Function : `set_SE_env()'. + + set_SE_env() + { + OPUS_DIR=/users/soft6/opus/DSM_SE5.2; export OPUS_DIR + + PATH=${PATH}:${OPUS_DIR}/tools/bin + PATH=${PATH}:${OPUS_DIR}/tools.sun4v/bin + PATH=${PATH}:${OPUS_DIR}/tools.sun4v/dfII/bin + PATH=${PATH}:${OPUS_DIR}/tools.sun4v/dsm/bin + PATH=${PATH}:${OPUS_DIR}/frame/bin + PATH=${PATH}:${OPUS_DIR}/bin + export PATH; hash -r + } + + +# -------------------------------------------------------------------- +# Function : `load_LEF_TECHNO_NAME()'. + + load_LEF_TECHNO_NAME() + { + if [ "$LEF_TECHNO_NAME" != "" ]; then + vecho 2 " o Loading LEF_TECHNO_NAME." + else + vecho 2 " o Loading default LEF_TECHNO_NAME." + LEF_TECHNO_NAME=$ALLIANCE_TOP/etc/cmos_12.lef + fi + + vecho 2 " - $LEF_TECHNO_NAME" + vecho 2 "" + add_script_SE_load lef $LEF_TECHNO_NAME \ + $script_SE_init > /dev/null 2>&1 + } + + +# -------------------------------------------------------------------- +# Function : `norm_CATA_DIR()'. + + norm_CATA_DIR() + { + aDir="$1" + + echo `echo $aDir | sed 's,//,/,g + s,/$,,'` + } + + +# -------------------------------------------------------------------- +# Function : `load_MBK_CATA_LIB()'. + + load_MBK_CATA_LIB() + { + vecho 1 " o Loading MBK_CATA_LIB." + NDIR=1 + CATA_dir=`echo ${MBK_CATA_LIB}:END | cut -d ':' -f $NDIR` + + while [ "$CATA_dir" != "END" ]; do + CATA_dir=`norm_CATA_DIR $CATA_dir` + + if [ "$CATA_dir" != "." ]; then + CATA_name=`echo $CATA_dir | sed 's,.*/,,'`.lef + + vecho 2 " - $CATA_dir/${CATA_name}" + if [ ! -f "$CATA_dir/${CATA_name}" ]; then + echo "sea:warning: LEF file not found \"$CATA_dir/${CATA_name}\"." + else + add_script_SE_load lef "$CATA_dir/${CATA_name}" \ + $script_SE_init > /dev/null 2>&1 + fi + fi + + NDIR=`expr $NDIR + 1` + CATA_dir=`echo ${MBK_CATA_LIB}:END | cut -d ':' -f $NDIR` + done + vecho 2 "" + } + + +# -------------------------------------------------------------------- +# Function : `rm_SE_db()'. + + rm_SE_db() + { + rm -f LBRARY.* *.dtp *.rpt *.opt.def *.opt.lef '&1' + } + + +# -------------------------------------------------------------------- +# Function : `rm_SEA_tmp()'. + + rm_SEA_tmp() + { + rm -f $script_SE_init $script_SE_load + } + + +# -------------------------------------------------------------------- +# Function : `clean_sea()'. + + clean_sea() + { + if [ "$TAIL_pid" != "" ]; then kill -KILL $TAIL_pid; fi + + if [ "$keepSE" = "n" ]; then rm_SE_db; fi + if [ "$keepTmp" = "n" ]; then rm_SEA_tmp; fi + } + + +# -------------------------------------------------------------------- +# Function : `abort_sea()'. + + abort_sea() + { + clean_sea + + exit 1 + } + + +# -------------------------------------------------------------------- +# Function : `add_script_SE_init()'. + + add_script_SE_init() + { + aScript="$1" + aMAC="$2" + + if [ ! -f "$aScript" ]; then + echo "sea.sh:error: Script not found: \"$aScript\"." + exit 1 + fi + + echo " EXEC $aScript ;" >> $aMAC + } + + +# -------------------------------------------------------------------- +# Function : `add_script_SE_load()'. + + add_script_SE_load() + { + aType="$1" + aFile="$2" + aMAC="$3" + + vecho 2 " - LEF/DEF/mac to load : \"$aFile\"." + + if [ ! -f "$aFile" ]; then + echo "sea.sh:error: LEF/DEF/mac not found: \"$aFile\"." + exit 1 + fi + + case $aType in + "lef") echo " INPUT LEF FILENAME \"$aFile\" ;" >> $aMAC;; + "def") echo " INPUT DEF FILENAME \"$aFile\" ;" >> $aMAC;; + "mac") echo " EXEC \"$aFile\" ;" >> $aMAC;; + *) echo "sea.sh(add_script_SE_load):error:" + echo " Invalid type \"$aType\"." + exit 1;; + esac + } + + +# /------------------------------------------------------------------\ +# | | +# | Main Part of the Shell Script | +# | | +# \------------------------------------------------------------------/ +# + + +# SIGINT : 2 (^C). +# SIGQUIT : 3 +# SIGTERM : 15 (sent from a kill). + trap abort_sea 2 3 15 + + +# -------------------------------------------------------------------- +# Process the command line. + + + devel="n" + keepSE="n" + keepTmp="n" + defLib="y" + argMemory="" + argJNL="-j=sea.jnl" + argGD="" + argBatch="" + + + rm -f $script_SE_init + rm -f $script_SE_load + + + while [ $# -gt 0 ]; do + + case $1 in + --devel) devel="y";; + --help) print_usage; exit 0;; + --verbose) VL=1;; + --very-verbose) VL=2;; + --keep-se) keepSE="y";; + --keep-tmp) keepTmp="y";; + --no-deflib) defLib="n";; + --ansi) argGD="-gd=ansi";; + --batch) argBatch="-b";; + --memory) + if [ $# -ge 2 ]; then + argMemory="-m=$2" + shift + else + echo "sea.sh:error: Missing argument." + print_usage; exit 1 + fi;; + + --*) echo "sea.sh:error: Invalid option \`$1'." + print_usage; exit 1;; + + -*) lSwitch="$1"; NB=2; CH=`echo $lSwitch | cut -c$NB` + + while [ "$CH" != "" ]; do + case $CH in + D) devel="y";; + h) print_usage; exit 0;; + v) VL=1;; + V) VL=2;; + K) keepSE="y";; + k) keepTmp="y";; + N) defLib="n";; + a) argGD="-gd=ansi";; + b) argBatch="-b";; + m) if [ $# -ge 2 ]; then + argMemory="-m=$2" + shift + else + echo "sea.sh:error: Missing argument." + print_usage; exit 1 + fi;; + + *) echo "sea.sh:error: Invalid option \`$CH'." + print_usage; exit 1;; + esac + + NB=`expr $NB + 1` + CH=`echo $lSwitch | cut -c$NB` + done;; + + *) # Unmatched argument, find if this is a LEF, DEF or mac file. + if echo "$1" | grep '\.lef$' > /dev/null 2>&1; then + add_script_SE_load lef "$1" $script_SE_load + else if echo "$1" | grep '\.def$' > /dev/null 2>&1; then + add_script_SE_load def "$1" $script_SE_load + else if echo "$1" | grep '\.mac$' > /dev/null 2>&1; then + add_script_SE_load mac "$1" $script_SE_load + else + echo "sea.sh:error: Invalid argument: \"$1\"." + print_usage; exit 1 + fi; fi; fi + ;; + esac + + shift + done + + + title + + +# -------------------------------------------------------------------- +# Consistency checks. + + + if [ -z "$ALLIANCE_TOP" ]; then + echo "sea.sh:error: \$ALLIANCE_TOP is not set, please set your Alliance" + echo " environment." + exit 1 + fi + if [ -z "$ALLIANCE_OS" ]; then + echo "sea.sh:error: \$ALLIANCE_OS is not set, please set your Alliance" + echo " environment." + exit 1 + fi + + if [ "$ALLIANCE_OS" != "Solaris" ]; then + echo "sea.sh:error: Must be run only under Solaris OS." + echo " (current OS : \"$ALLIANCE_OS\")" + exit 1 + fi + + + if [ "$devel" = "y" ]; then + ALLIANCE_TOP="/users/cao/jpc/alliance/archi/$ALLIANCE_OS" + + echo "WARNING:" + echo "WARNING: You are using the developement version." + echo "WARNING: Resetting \$ALLIANCE_TOP to \"$ALLIANCE_TOP\"." + echo "WARNING:" + echo "" + echo "" + fi + + +# -------------------------------------------------------------------- +# Script at work. + + + rm_SE_db + set_SE_env + + if [ "$defLib" = "y" ]; then + vecho 2 " o Loading defaults settings." + vecho 2 "" + add_script_SE_init $ALLIANCE_TOP/etc/se_defaults.mac $script_SE_init + + load_LEF_TECHNO_NAME + load_MBK_CATA_LIB + fi + if [ -f "$script_SE_load" ]; then + cat "$script_SE_load" >> "$script_SE_init" + fi + + vecho 1 " o Running Silicon Ensemble." + if [ ! -f "$script_SE_init" ]; then + sedsm $argMemory $argJNL $argGD $argBatch & + SE_pid="$!" + + if [ $VL -ge 2 ]; then + sleep 2; tail -f sea.jnl & + TAIL_pid="$!" + fi + wait $SE_pid + else + if [ "$argBatch" != "" ]; then + if [ $VL -ge 2 ]; then + echo " o Silicon Ensemble output follow (in 2s)." + + (sleep 5; exec tail -f sea.jnl) & + TAIL_pid="$!" + fi + + SE_pid=`sedsm $argMemory \ + $argJNL \ + $argGD \ + $argBatch \ + "EXEC $script_SE_init ;" 2>&1 > /dev/null |\ + sed '1d + s,.*\[\([0-9]*\)\] Forking.*,\1,'` + else + sedsm $argMemory $argJNL $argGD "EXEC $script_SE_init ;" + fi + + #echo "$SE_pid" > SE_pid + #echo " o SE has forked." + + fi + + + clean_sea + + +# -------------------------------------------------------------------- +# That's all Folks. + + vecho 2 "" + vecho 2 "" + exit 0 diff --git a/alliance/src/sea/src/seplace.sh b/alliance/src/sea/src/seplace.sh new file mode 100755 index 00000000..0a6da0d7 --- /dev/null +++ b/alliance/src/sea/src/seplace.sh @@ -0,0 +1,463 @@ +#!/bin/sh +# +# $Id: seplace.sh,v 1.1 2002/04/25 16:16:20 jpc Exp $ +# +# /------------------------------------------------------------------\ +# | | +# | A l l i a n c e C A D S y s t e m | +# | S i l i c o n E n s e m b l e / A l l i a n c e | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : alliance-support@asim.lip6.fr | +# | ================================================================ | +# | Script : "./seplace.sh" | +# | **************************************************************** | +# | U p d a t e s | +# | | +# \------------------------------------------------------------------/ +# + + +# -------------------------------------------------------------------- +# Constants definitions. + + VL=0 + LOG="./seplace.log" + DEF_UNITS=100 + + +# /------------------------------------------------------------------\ +# | | +# | Functions Definitions | +# | | +# \------------------------------------------------------------------/ +# +# -------------------------------------------------------------------- +# Function : "vecho()". + + vecho() + { + if [ $1 -le $VL ]; then + if [ "$2" = "-n" ]; then + printf "$3" + else + echo "$2" + fi + fi + } + + +# -------------------------------------------------------------------- +# Function : "title()". + + title() + { + #if [ $VL -ge 1 ]; then + # echo "" + alcbanner "SEplace" "1.00" \ + "Alliance Silicon Ensemble Placer Front End" "2000" + echo "" + #fi + } + + +# -------------------------------------------------------------------- +# Function : `print_usage()'. + + print_usage() + { + echo "" + echo "" + echo "Usage: sea.sh [--verbose|-v] [--very-verbose|-V] [--help|-h] \\" + echo " [--memory=] \\" + echo " [--ioc] [--4] [--all] [--partial-place=] \\" + echo " [--rows=] [--power=] [--margin=] \\" + echo " " + echo "" + echo "Options:" + echo " o [--help] : Print this help." + echo " o [--verbose] : Be verbose." + echo " o [--very-verbose] : Be very verbose :-)." + echo " o [--all] : Sets the number of routing layers avalai-" + echo " bles to the router to 6. By default only 3 will be used." + echo " o [--4] : Uses ALU2, ALU3 & ALU4." + echo " o [--memory=] : Sets the amount of memory used by" + echo " Silicon Ensemble. Avalaible are : " + echo " 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 150, 200, 250," + echo " 300, 400, 500, 800, 1200, 1600, 1900." + echo " o [--partial-place=] :" + echo " The design is already partially placed (there must be a" + echo " physical view describing this partial placement)." + echo " o [--ioc] : Load a terminal placement file." + echo " (named .ioc)." + echo " o [--rows=] : The placement will have rows." + echo " (by default the layout will have an aspect ratio of 1)" + echo " o [--power=] : The design will have vertical power" + echo " stripes (each stripe have a width of 35l)." + echo " o [--margin=] :" + echo " The amount of free area added, in percentage of the cells" + echo " area. The resulting area will be equal to" + echo " CELL_AREA * (1 + /100). Default value : 10." + echo " o : The netlist name (mandatory)." + echo " o : The resulting layout name (mandatory)." + echo " By default the same as the netlist name, will erase any" + echo " pre-placement." + echo "" + echo "" + } + + +# -------------------------------------------------------------------- +# Function : `log_exec()'. + + log_exec() + { + eval "$1" >> $LOG 2>&1 + value="$?" + if [ $value -ne 0 ]; then + echo "seplace.sh: \"$1\"." + echo "seplace.sh:error: command failed." + exit 1 + fi + return $value + } + + +# -------------------------------------------------------------------- +# Function : `MBK_env()'. + + MBK_env() + { + vecho 1 " o Current Alliance environment:" + vecho 1 " - ALLIANCE_TOP : ${ALLIANCE_TOP-not set}" + vecho 1 " - ALLIANCE_OS : ${ALLIANCE_OS-not set}" + vecho 1 " o Current MBK environment:" + vecho 1 " - MBK_IN_LO : ${MBK_IN_LO-not set}" + vecho 1 " - MBK_OUT_LO : ${MBK_OUT_LO-not set}" + vecho 1 " - MBK_IN_PH : ${MBK_IN_PH-not set}" + vecho 1 " - MBK_OUT_PH : ${MBK_OUT_PH-not set}" + vecho 1 " - MBK_WORK_LIB : ${MBK_WORK_LIB-not set}" + vecho 1 -n " - MBK_CATA_LIB : " + + if [ -z "$MBK_CATA_LIB" ]; then + vecho 1 "not set" + else + STRING=`echo ${MBK_CATA_LIB} | \ + awk 'BEGIN { FS=":"; } \ + { for( i=1; i<=NF; i++) { \ + printf("%s\n", $i); \ + if (i < NF) \ + printf(" "); \ + } \ + }' -` + vecho 1 "$STRING" + fi + + vecho 1 " - MBK_CATAL_NAME : ${MBK_CATAL_NAME-not set}" + vecho 1 " - MBK_VDD : ${MBK_VDD-not set}" + vecho 1 " - MBK_VSS : ${MBK_VSS-not set}" + vecho 1 " - RDS_TECHNO_NAME : ${RDS_TECHNO_NAME-not set}" + vecho 1 "" + vecho 1 "" + } + + +# -------------------------------------------------------------------- +# Function : `get_number()'. + + get_number() + { + number=`echo $1 | cut -d '=' -f 2` + + #notDigit=`echo $number | sed 's,[0-9],,'` + #if [ "$notDigit" != "" ]; then echo $noDigit >&2; exit 1; fi + + echo $number + } + + +# -------------------------------------------------------------------- +# Function : `get_string()'. + + get_string() + { + string=`echo $1 | cut -d '=' -f 2` + + echo $string + } + + +# -------------------------------------------------------------------- +# Function : `rm_SEplace_tmp()'. + + rm_SEplace_tmp() + { + RM_PREV_RUN="n" + + while [ $# -gt 0 ]; do + case $1 in + "--previous-run") RM_PREV_RUN="y";; + esac + + shift + done + + rm -f ${netlistName}_p.mac + rm -f ${netlistName}.def + rm -f ${netlistName}_p.def + + if [ "$RM_PREV_RUN" = "y" ]; then + rm -f ${placementName}_p.$MBK_IN_PH + fi + } + + +# /------------------------------------------------------------------\ +# | | +# | Main Part of the Shell Script | +# | | +# \------------------------------------------------------------------/ +# + + + rm -f $LOG + + + title + + + if [ "`uname`" != "SunOS" ]; then + echo "seplace.sh:error: This progam must be run under Solaris." + exit 1 + fi + + +# -------------------------------------------------------------------- +# Process the command line. + + + keepTmp="n" + margin="10" + powerNumber="1" + rowNumber="" + argRows="" + memNumber="150" + netlistName="" + partialName="" + placementName="" + ioc="n" + argVL="" + argLayers="-3" + argsA2DEF="-V -t -c -e" + argsDEF2A="-V -p -S -i -b" + argsSEA="--batch --ansi" +# argsSEA="-V" + + + if [ $# -eq 0 ]; then + print_usage + exit 0 + fi + + + while [ $# -gt 0 ]; do + + case $1 in + --keep-tmp) keepTmp="y";; + --devel) argsSEA="$argsSEA --devel";; + --help) print_usage; exit 0;; + --verbose) VL=1; argVL="-v";; + --very-verbose) VL=2; argVL="-V";; + --ioc) ioc="y";; + --all) argLayers="-6";; + --4) argLayers="-4";; + --partial-place=*) partialName=`get_string $1`;; + --rows=*) rowNumber=`get_number $1` + if [ $? -ne 0 ]; then + echo -n "seplace.sh:error: Bad number `get_number $1`" + echo " in argument \"$1\"." + print_usage + exit 1 + fi;; + --margin=*) margin=`get_number $1` + if [ $? -ne 0 ]; then + echo -n "seplace.sh:error: Bad number" + echo " in argument \"$1\"." + print_usage + exit 1 + fi;; + --power=*) powerNumber=`get_number $1` + if [ $? -ne 0 ]; then + echo -n "seplace.sh:error: Bad number" + echo " in argument \"$1\"." + print_usage + exit 1 + fi;; + --memory=*) memNumber=`get_number $1` + if [ $? -ne 0 ]; then + echo -n "seplace.sh:error: Bad number" + echo " in argument \"$1\"." + print_usage + exit 1 + fi;; + + --*) echo "seplace.sh:error: Invalid option \`$1'." + print_usage; exit 1;; + + -*) lSwitch="$1"; NB=2; CH=`echo $lSwitch | cut -c$NB` + + while [ "$CH" != "" ]; do + case $CH in + h) print_usage; exit 0;; + v) VL=1; argVL="-v";; + V) VL=2; argVL="-V";; + k) keepTmp="y";; + + *) echo "sea.sh:error: Invalid option \`$CH'." + print_usage; exit 1;; + esac + + NB=`expr $NB + 1` + CH=`echo $lSwitch | cut -c$NB` + done;; + + *) # Unmatched argument, this is the netlist name. + if [ "$netlistName" = "" ]; then + netlistName=$1 + else if [ "$placementName" = "" ]; then + placementName=$1 + else + echo "seplace.sh:warning: Ignored extra argument \`$1'." + fi; fi + ;; + esac + + shift + done + + +# -------------------------------------------------------------------- +# Consistency checks. + + + if [ "$netlistName" = "" ]; then + echo "seplace.sh:error: Missing argument." + print_usage + exit 1 + else + if [ ! -f "$netlistName".$MBK_IN_LO ]; then + echo -n "seplace.sh:error: Can't find netlist file" + echo " \"$netlistName.$MBK_IN_LO\"." + print_usage; exit 1 + fi + fi + + + if [ "$placementName" = "" ]; then + echo "seplace.sh:error: Missing argument." + print_usage + exit 1 + fi + + + if [ "$partialName" != "" -a ! -f "$partialName".$MBK_IN_PH ]; then + echo -n "seplace.sh:error: Can't find pre-placement file" + echo " \"$partialName.$MBK_IN_PH\"." + print_usage; exit 1 + fi + + + if [ "$ioc" = "y" -a ! -f "$netlistName.ioc" ]; then + echo -n "seplace.sh:error: Can't find terminal placement file" + echo " \"$netlistName.ioc\"." + print_usage; exit 1 + fi + + + if [ "$partialName" != "" -a "$rowNumber" != "" ]; then + echo "seplace.sh:warning: As a partial placement is supplied, the row" + echo " number will be ignored." + print_usage; exit 1 + fi + + +# -------------------------------------------------------------------- +# Script at work. + + + MBK_env + rm_SEplace_tmp --previous-run + + + argsA2DEF="$argsA2DEF $argLayers" + + + vecho 1 " o Netlist file is := \"$netlistName.$MBK_IN_LO\"." + argsA2DEF="$argsA2DEF --mac-place=${netlistName}_p" + + + if [ "$partialName" != "" ]; then + vecho 1 " o Partial placement file is := \"$partialName.$MBK_IN_PH\"." + argsA2DEF="$argsA2DEF --place=$partialName" + rowNumber="" + margin="0" + else + vecho 1 " o Automatic floorplan generation." + argsA2DEF="$argsA2DEF -F" + fi + + + if [ "$rowNumber" != "" ]; then + vecho 2 " - placement will have $rowNumber rows." + argsA2DEF="$argsA2DEF --row-number=$rowNumber" + fi + + + if [ "$margin" != "0" ]; then + vecho 2 " - Increasing cell area by $margin percent." + argsA2DEF="$argsA2DEF --margin=$margin" + fi + + + if [ "$powerNumber" != "1" ]; then + vecho 2 " - placement will have $powerNumber power." + argsA2DEF="$argsA2DEF --power=$powerNumber" + fi + + + if [ "$ioc" = "y" ]; then + vecho 1 " o IO placement file is := \"$netlistName.ioc\"." + argsA2DEF="$argsA2DEF --ioc" + fi + + + vecho 1 " o Silicon ensemble memory used := $memNumber." + argsSEA="$argsSEA --memory $memNumber" + + + vecho 2 "" + vecho 2 " o Translating \"$netlistName\" into DEF format." + log_exec "a2def $argsA2DEF $netlistName" + + + vecho 2 "" + vecho 2 " o Silicon Ensemble." + + + vecho 2 " - Running SEA/SE..." + sea $argVL $argsSEA $netlistName.def ${netlistName}_p.mac + cat sea.jnl >> $LOG + rm sea.jnl + + + vecho 2 "" + vecho 2 " o Translating \"$netlistName\" back into Alliance format." + log_exec "def2a $argsDEF2A ${netlistName}_p ${placementName}" + + + if [ "$keepTmp" = "n" ]; then + rm_SEplace_tmp + fi + + + exit 0 diff --git a/alliance/src/sea/src/seroute.sh b/alliance/src/sea/src/seroute.sh new file mode 100755 index 00000000..0388182c --- /dev/null +++ b/alliance/src/sea/src/seroute.sh @@ -0,0 +1,430 @@ +#!/bin/sh +# +# $Id: seroute.sh,v 1.1 2002/04/25 16:16:20 jpc Exp $ +# +# /------------------------------------------------------------------\ +# | | +# | A l l i a n c e C A D S y s t e m | +# | S i l i c o n E n s e m b l e / A l l i a n c e | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : alliance-support@asim.lip6.fr | +# | ================================================================ | +# | Script : "./seroute.sh" | +# | **************************************************************** | +# | U p d a t e s | +# | | +# \------------------------------------------------------------------/ +# + + +# -------------------------------------------------------------------- +# Constants definitions. + + VL=0 + LOG="./seroute.log" + DEF_UNITS=100 + + +# /------------------------------------------------------------------\ +# | | +# | Functions Definitions | +# | | +# \------------------------------------------------------------------/ +# +# -------------------------------------------------------------------- +# Function : "vecho()". + + vecho() + { + if [ $1 -le $VL ]; then + if [ "$2" = "-n" ]; then + printf "$3" + else + echo "$2" + fi + fi + } + + +# -------------------------------------------------------------------- +# Function : "title()". + + title() + { + #if [ $VL -ge 1 ]; then + # echo "" + alcbanner "SEroute" "1.00" \ + "Alliance Silicon Ensemble Router Front End" "2000" + echo "" + #fi + } + + +# -------------------------------------------------------------------- +# Function : `print_usage()'. + + print_usage() + { + echo "" + echo "" + echo "Usage: seroute [--verbose|-v] [--very-verbose|-V] [--help|-h] \\" + echo " [--memory=] \\" + echo " [--core] [--ring] [--ioc] [--all] [--4] \\" + echo " [--trust-orient] [--no-power] [--generator] \\" + echo " [--place=] \\" + echo " " + echo "" + echo "Options:" + echo " o [--help] : Print this help." + echo " o [--verbose] : Be verbose." + echo " o [--very-verbose] : Be very verbose :-)." + echo " o [--memory=] : Sets the amount of memory used by" + echo " Silicon Ensemble. Avalaible are : " + echo " 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 150, 200, 250," + echo " 300, 400, 500, 800, 1200, 1600, 1900." + echo " o [--ioc] : Load a terminal placement file." + echo " (named .ioc)." + echo " o [--all] : Use all 6 layers for routing." + echo " o [--4] : Use only ALU2 to ALU4 for routing." + echo " o [--core] : Route terminals to the edge of the" + echo " abutment-box." + echo " o [--ring] : Produce a layout suitable for ring." + echo " This option implies \"--core\"." + echo " o [--trust-orient] : Trust MBK orientation, i.e. allow cells" + echo " without regular vdd/vss power rails." + echo " o [--no-power] : Do not route power rails, this implies" + echo " that they must be pre-routed by the user." + echo " o [--generator] : Route a user build block like a RAM" + echo " or a ROM. This allow the generator leaf cells not to" + echo " comply strictly to the SxLib requirements. This option is" + echo " equivalent to --no-power --trust-orient." + echo " o [--place=] : The name of the placement file," + echo " (if different from the netlist)." + echo " o : The netlist name (mandatory)." + echo " o : The resulting layout name (mandatory)." + echo "" + echo "" + } + + +# -------------------------------------------------------------------- +# Function : `get_number()'. + + get_number() + { + number=`echo $1 | cut -d '=' -f 2` + + #notDigit=`echo $number | sed 's,[0-9],,'` + #if [ "$notDigit" != "" ]; then echo $noDigit >&2; exit 1; fi + + echo $number + } + + +# -------------------------------------------------------------------- +# Function : `log_exec()'. + + log_exec() + { + eval "$1" >> $LOG 2>&1 + value="$?" + if [ $value -ne 0 ]; then + echo "seroute.sh: \"$1\"." + echo "seroute.sh:error: command failed." + exit 1 + fi + return $value + } + + +# -------------------------------------------------------------------- +# Function : `MBK_env()'. + + MBK_env() + { + vecho 1 " o Current Alliance environment:" + vecho 1 " - ALLIANCE_TOP : ${ALLIANCE_TOP-not set}" + vecho 1 " - ALLIANCE_OS : ${ALLIANCE_OS-not set}" + vecho 1 " o Current MBK environment:" + vecho 1 " - MBK_IN_LO : ${MBK_IN_LO-not set}" + vecho 1 " - MBK_OUT_LO : ${MBK_OUT_LO-not set}" + vecho 1 " - MBK_IN_PH : ${MBK_IN_PH-not set}" + vecho 1 " - MBK_OUT_PH : ${MBK_OUT_PH-not set}" + vecho 1 " - MBK_WORK_LIB : ${MBK_WORK_LIB-not set}" + vecho 1 -n " - MBK_CATA_LIB : " + + if [ -z "$MBK_CATA_LIB" ]; then + vecho 1 "not set" + else + STRING=`echo ${MBK_CATA_LIB} | \ + awk 'BEGIN { FS=":"; } \ + { for( i=1; i<=NF; i++) { \ + printf("%s\n", $i); \ + if (i < NF) \ + printf(" "); \ + } \ + }' -` + vecho 1 "$STRING" + fi + + vecho 1 " - MBK_CATAL_NAME : ${MBK_CATAL_NAME-not set}" + vecho 1 " - MBK_VDD : ${MBK_VDD-not set}" + vecho 1 " - MBK_VSS : ${MBK_VSS-not set}" + vecho 1 " - RDS_TECHNO_NAME : ${RDS_TECHNO_NAME-not set}" + vecho 1 "" + vecho 1 "" + } + + +# -------------------------------------------------------------------- +# Function : `rm_SEroute_tmp()'. + + rm_SEroute_tmp() + { + RM_PREV_RUN="n" + + while [ $# -gt 0 ]; do + case $1 in + "--previous-run") RM_PREV_RUN="y";; + esac + + shift + done + + rm -f ${netlistName}_r.mac + rm -f ${netlistName}.def + rm -f ${netlistName}_r.def + + if [ "$RM_PREV_RUN" = "y" ]; then + rm -f ${layoutName}_r.$MBK_IN_PH + fi + } + + +# -------------------------------------------------------------------- +# Function : `get_string()'. + + get_string() + { + string=`echo $1 | cut -d '=' -f 2` + + echo $string + } + + +# /------------------------------------------------------------------\ +# | | +# | Main Part of the Shell Script | +# | | +# \------------------------------------------------------------------/ +# + + + rm -f $LOG + + + title + + + if [ "`uname`" != "SunOS" ]; then + echo "seplace.sh:error: This progam must be run under Solaris." + exit 1 + fi + + +# -------------------------------------------------------------------- +# Process the command line. + + + keepTmp="n" + memNumber="150" + netlistName="" + placementName="" + layoutName="" + ioc="n" + core="n" + ring="n" + argVL="" + argLayers="-3" + argFillTie="" + argsA2DEF="-V -p" + argsDEF2A="-V -p" +# argsA2DEF="-V -p -E" +# argsDEF2A="-V -p -S" + argsSEA="--batch --ansi" +# argsSEA="-V" + + + if [ $# -eq 0 ]; then + print_usage + exit 0 + fi + + + while [ $# -gt 0 ]; do + + case $1 in + --devel) argsSEA="$argsSEA --devel";; + --help) print_usage; exit 0;; + --verbose) VL=1; argVL="-v";; + --very-verbose) VL=2; argVL="-V";; + --keep-tmp) keepTmp="y";; + --ioc) ioc="y";; + --core) core="y";; + --ring) ring="y"; core="y";; + --all) argLayers="-6";; + --4) argLayers="-4";; + --fill-tie) argFillTie="-t";; + --trust-orient) argsA2DEF="$argsA2DEF -T";; + --no-power) argsA2DEF="$argsA2DEF -n";; + --generator) argsA2DEF="$argsA2DEF -T -n";; + --place=*) placementName=`get_string $1`;; + --memory=*) memNumber=`get_number $1` + if [ $? -ne 0 ]; then + echo -n "seplace.sh:error: Bad number" + echo " in argument \"$1\"." + print_usage + exit 1 + fi;; + + --*) echo "seroute.sh:error: Invalid option \`$1'." + print_usage; exit 1;; + + -*) lSwitch="$1"; NB=2; CH=`echo $lSwitch | cut -c$NB` + + while [ "$CH" != "" ]; do + case $CH in + h) print_usage; exit 0;; + k) keepTmp="y";; + v) VL=1; argVL="-v";; + V) VL=2; argVL="-V";; + + *) echo "sea.sh:error: Invalid option \`$CH'." + print_usage; exit 1;; + esac + + NB=`expr $NB + 1` + CH=`echo $lSwitch | cut -c$NB` + done;; + + *) # Unmatched argument, this is the netlist name. + if [ "$netlistName" = "" ]; then + netlistName=$1 + else if [ "$layoutName" = "" ]; then + layoutName=$1 + else + echo "seroute.sh:warning: Ignored extra argument \`$1'." + fi; fi + ;; + esac + + shift + done + + +# -------------------------------------------------------------------- +# Consistency checks. + + + if [ "$netlistName" = "" ]; then + echo "seplace.sh:error: Missing argument." + print_usage + exit 1 + else + if [ ! -f "$netlistName.$MBK_IN_LO" ]; then + echo -n "seroute.sh:error: Can't find netlist file" + echo " \"$netlistName.$MBK_IN_LO\"." + print_usage; exit 1 + fi + fi + + + if [ "$placementName" = "" ]; then placementName=$netlistName; fi + + if [ ! -f "$placementName".$MBK_IN_PH ]; then + echo -n "seroute.sh:error: Can't find placement file" + echo " \"$placementName.$MBK_IN_PH\"." + print_usage; exit 1 + fi + + argsA2DEF="$argsA2DEF --place=$placementName" + + + if [ "$layoutName" = "" ]; then + echo "seplace.sh:error: Missing argument." + print_usage + exit 1 + fi + + + if [ "$ioc" = "y" -a ! -f "$netlistName.ioc" ]; then + echo -n "seroute.sh:error: Can't find terminal placement file" + echo " \"$netlistName.ioc\"." + print_usage; exit 1 + fi + + +# -------------------------------------------------------------------- +# Script at work. + + + MBK_env + rm_SEroute_tmp --previous-run + + + argsA2DEF="$argsA2DEF $argLayers $argFillTie" + + + vecho 1 " o Netlist file is := \"$netlistName.$MBK_IN_LO\"." + argsA2DEF="$argsA2DEF --mac-route=${netlistName}_r" + + + if [ "$ioc" = "y" ]; then + vecho 1 " o IO placement file is := \"$netlistName.ioc\"." + argsA2DEF="$argsA2DEF --ioc" + fi + + + if [ "$core" = "y" ]; then + vecho 1 " o The design will have pins." + argsA2DEF="$argsA2DEF -c" + fi + + + if [ "$ring" = "y" ]; then + vecho 1 " o Merge power terminals for ring." + argsDEF2A="$argsDEF2A -r" + fi + + + vecho 1 " o Silicon ensemble memory used := $memNumber." + argsSEA="$argsSEA --memory $memNumber" + + + vecho 2 "" + vecho 2 " o Translating \"$netlistName\" into DEF format." + log_exec "a2def $argsA2DEF $netlistName" + + + vecho 2 "" + vecho 2 " o Silicon Ensemble." + + + vecho 2 " - Running SEA/SE..." + sea $argVL $argsSEA $netlistName.def ${netlistName}_r.mac + cat sea.jnl >> $LOG + rm sea.jnl + + + vecho 2 "" + vecho 2 " o Translating \"$netlistName\" back into Alliance format." + log_exec "def2a $argsDEF2A ${netlistName}_r ${layoutName}" + + + if [ "$keepTmp" = "n" ]; then + rm_SEroute_tmp + fi + + + exit 0 diff --git a/alliance/src/sea/src/sxlib2LEF.c b/alliance/src/sea/src/sxlib2LEF.c new file mode 100644 index 00000000..a4c0a0b7 --- /dev/null +++ b/alliance/src/sea/src/sxlib2LEF.c @@ -0,0 +1,114 @@ +/* + * $Id: sxlib2LEF.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./LEF_drive_sxlib.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" +# include "LEF_drive_sxlib.h" + + +/* ---------------------------------------------------------------------- + * Internal functions declarations. + */ + + static void printHelp __FP((void)); + + +/* + * /--------------------------------------------------------------------\ + * | Functions Definitions | + * \--------------------------------------------------------------------/ + */ + +/* ---------------------------------------------------------------------- + * Function : "printHelp()". + */ + +static void printHelp() +{ + printf(" o Usage := \"sxlib2lef [options] \"\n\n"); + printf(" o Options :\n"); + printf(" -v := Be verbose.\n"); + printf(" -V := Be very verbose.\n"); + printf(" -h := Print this message.\n"); + printf(" -o := Allow offgrid terminals.\n"); + printf(" -p := Do not generate power PORT geometries.\n"); + printf("\n" ); +} + + +/* ---------------------------------------------------------------------- + * Function : "main()". + */ + +extern int main(argc, argv) + int argc; + char *argv[]; +{ + struct lofig *pLofig; + struct phfig *pPhfig; + long VL, sxFlags; + int argC, i; + + + /* Read MBK environment. */ + mbkenv(); + + /* Initialise the "Ut" module. */ + util_init(C_VerboseLevel2, F_DUMPCORE, "sx2LEF"); + + + argC = argc; + + /* Default options. */ + VL = C_VerboseLevel0; + sxFlags = FALSE; + + /* Read the options. */ + for(i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-h")) { printHelp(); exit(0); } + if (!strcmp(argv[i], "-v")) { VL = C_VerboseLevel1; continue; } + if (!strcmp(argv[i], "-V")) { VL = C_VerboseLevel2; continue; } + if (!strcmp(argv[i], "-o")) { sxFlags |= F_ALLOW_OFFGRID; continue; } + if (!strcmp(argv[i], "-p")) { sxFlags |= F_NO_POWER_GEOM; continue; } + + break; + } + + if ((argC - i) != 1) { printHelp(); exit(1); } + + + setVL(VL); + + if (VL > C_VerboseLevel0) + alliancebanner( + "sx2LEF", "V.RR", "SxLib to LEF MACRO converter", + "2000", ALLIANCE_VERSION ); + + printMBKEnv(); + + mprintf1 (" o Processing cell \"%s\".\n", argv[i]); + + pPhfig = getphfig(argv[i], 'A'); + pLofig = getlofig(argv[i], 'P'); + + + lefsavesxlophfig (pLofig, pPhfig, sxFlags); + + + exit(0); +} diff --git a/alliance/src/sea/src/util_Defs.h b/alliance/src/sea/src/util_Defs.h new file mode 100644 index 00000000..22a5bb7c --- /dev/null +++ b/alliance/src/sea/src/util_Defs.h @@ -0,0 +1,544 @@ +/* + * $Id: util_Defs.h,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Header : "./util_Defs.h" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# ifndef __util_Defs__ +# define __util_Defs__ + + +# include +# include +# include +# include +# include +# include +# include +# include +# include + + +/* ---------------------------------------------------------------------- + * Looks if functions prototypes are availables. + */ + +# ifndef __FP +# ifdef __STDC__ + /* Compiler is ANSI C compliant. */ +# include +# include + +# define __FP( arguments ) arguments +# define __FPV( arguments ) arguments + +# define __KR_C( code ) +# define __ANSI_C( code ) code +# else + /* Compiler is K&R C. */ +# include +# include + +# define __FP( arguments ) () +# define __FPV( arguments ) (va_alist) va_dcl + +# define __KR_C( code ) code +# define __ANSI_C( code ) +# endif +# endif + + +/* ---------------------------------------------------------------------- + * Missing GNU functions prototypes under GCC/SunOS 4.1.4. + */ + +# include "GNU_Defs.h" + + +/* ---------------------------------------------------------------------- + * Miscellaneous. + */ + +# define TRUE 1 +# define FALSE 0 + +# define m_Max(a,b) (((a) > (b)) ? (a) : (b)) +# define m_Min(a,b) (((a) > (b)) ? (b) : (a)) +# define ABS(a) (((a) > 0 ) ? (a) : -(a)) + + + /* Usual types shortcut. */ + + + + +/* ---------------------------------------------------------------------- + * Alliance Includes. + */ + +# include +# include +# include +# include +# include +# include + + + + +/* ---------------------------------------------------------------------- + * Module : "util_Sys.c" + */ + +# define F_DUMPCORE 0 +# define F_NOCORE 1 + +# define C_SIGTFLT ((int)1) +# define C_SIGERR ((int)2) + +# define C_VerboseLevel0 (0L) +# define C_VerboseLevel1 (1L) +# define C_VerboseLevel2 (2L) + +# define SIZE_S64 2048 + + + /* External variables from the various modules. */ + extern long util_VL; + extern long util_flags; + extern char util_binName[1024]; + + /* Interruptions handling functions. */ + extern void trapInit __FP((void)); + extern void sendGSignal __FP((int aSig)); + extern void setBinName __FP((char *asName)); + + /* Errors printing functions. */ + extern void stdflush __FP((void)); + extern void errMBK __FP((char *asName)); + extern void eprinth __FP((char *asName)); + extern int eprintf __FPV((char *aFormat, ...)); + extern int eprints __FP((char *aS)); + + /* Warnings printing functions. */ + extern void warnMBK __FP((char *asName)); + extern void wprinth __FP((char *asName)); + extern int wprintf __FPV((char *aFormat, ...)); + extern int wprints __FP((char *aS)); + + /* Messages printing functions. */ + extern void setVL __FP((long aVL)); + extern long getVL __FP((void)); + extern int vmprintf __FP((long aVL, char *aFormat, va_list aArgList)); + extern int mprintf __FPV((long aVL, char *aFormat, ...)); + extern int mprints __FP((long aVL, char *aS)); + extern int mprintf0 __FPV((char *aFormat, ...)); + extern int mprintf1 __FPV((char *aFormat, ...)); + extern int mprintf2 __FPV((char *aFormat, ...)); + + /* "util_init" global initialisation function. */ + extern void util_init __FP((long aVL, long aFlags, char *asName)); + + /* Persistent strings printing function (up to 64 strings). */ + extern char *s64printf __FPV((char *aFormat, ...)); + + /* Miscellaneous. */ + extern char *strtoup __FP((char *aS)); + + + + +/* ---------------------------------------------------------------------- + * Module : "util_Inter.c" + */ + + + /* Interval list element. */ + typedef struct eInter_s { + long min; + long max; + struct eInter_s *next; + } eInter_t; + + /* Interval list head. */ + typedef struct lInter_s { + long min; + long max; + long len; + struct eInter_s *l; + } lInter_t; + + + extern void printinter __FP((struct lInter_s *apInter)); + extern struct lInter_s *addinter __FP((struct lInter_s *apInter, + long aMin, + long aMax)); + extern void freeinter __FP((struct lInter_s *apInter)); + + +/* ---------------------------------------------------------------------- + * Module : "util_MBK.c" + */ + + +# define F_EQUAL (1L) +# define F_CALU (2L) +# define F_TALU (4L) +# define F_EQUAL_M (F_EQUAL) +# define F_EQUAL_C (F_EQUAL | F_CALU) +# define F_EQUAL_T (F_EQUAL | F_TALU) + +# define PTYPE_LOSEG 512 +# define PTYPE_TLOSEG 513 +# define PTYPE_ULOCON 514 + +# define LOSEG_VIA 1 +# define LOSEG_SEG 2 +# define LOSEG_CON 3 +# define LOSEG_SEGCON 4 + +# define F_HAS_SUBNET (1L<<0) +# define F_NET_ROUTED (1L<<1) +# define F_SUBNET_ROUTED (1L<<2) + + +# define MBKSCALE(l) ((l) * SCALE_X) +# define MBKUNSCALE(l) ((l) / SCALE_X) +# define NEWSIGINDEX (++MBK_sigIndex) + + + /* Model of physical VIA. */ + typedef struct eMVIA_s { + char type; + long width; + long height; + struct eMVIA_s *next; + } eMVIA_t; + + + /* Added to each segment (USER pointer). */ + typedef struct eLoseg_s { + long type; + void *MBKobj; + struct eLoseg_s *next; + } eLoseg_t; + + + /* Added to the phfig (USER pointer). */ + typedef struct tLoseg_s { + long sigNB; /* Number of signals. */ + long tSize; /* Real table size. */ + struct authtable *tHT; /* Sig name --> tLoseg index. */ + long *tAccess; /* Number of signal accesses. */ + long *tFlags; /* Some flags... */ + struct eLoseg_s **tLoseg; /* Head of signal seg list. */ + struct eMVIA_s *tMVIA; /* list of model VIAS. */ + } tLoseg_t; + + + extern long MBK_sigIndex; + + + extern long isobs __FP((struct phseg *apSeg)); + extern long getsigaliasnumber __FP((struct losig *apLosig)); + extern long signamecmp __FP((char *aLoname, char *aPhname)); + extern char **makesegnamelist __FP((char *aName)); + extern void printMBKEnv __FP((void)); + extern char getAltVIALayer __FP((char aVIA, char aLayer)); + extern char getTopVIALayer __FP((char aVIA)); + extern char getBottomVIALayer __FP((char aVIA)); + extern char getTurnVIA __FP((char aLayer)); + extern long isVIALayer __FP((char aVIA, char aLayer)); + extern long getUpVIALayer __FP((char aVIA, char aLayer)); + extern char getUpLayer __FP((char aLayer)); + extern long cmpALU __FP((char aLayer1, char aLayer2)); + extern char getALU __FP((char aLayer)); + extern char getCALU __FP((char aLayer)); + extern long isCALU __FP((char aLayer)); + extern char getTALU __FP((char aLayer)); + extern long getLayerTrackWidth __FP((char aLayer)); + extern void xyflatseg __FP((struct phseg *apFlatSeg, + struct phseg *apSeg, + long aXINS, long aYINS, + long aXAB1, long aYAB1, + long aXAB2, long aYAB2, + char aTransf)); + extern void xyflatvia __FP((struct phvia *apFlatVIA, + struct phvia *apVIA, + long aXINS, long aYINS, + long aXAB1, long aYAB1, + long aXAB2, long aYAB2, + char aTransf)); + + /* Utilities for pad power splitting. */ + extern long isPad __FP((char *asCell)); + extern long initSigIndex __FP((struct losig *apLoSig)); + extern long cmpSigName __FP((struct losig *apLoSig, char *asName)); + extern struct locon *addInsLoCon __FP((struct loins *apIns, + char *asName, + struct losig *apSig, + char aDir)); + extern void splitPowerNet __FP((struct lofig *apLoFig, + char *asPower)); + extern struct phins *findphins __FP((struct phfig *apPhfig, + char *insName)); + extern struct phins *findphmodel __FP((struct phfig *apPhfig, + char *modelName)); + extern struct locon *findlocon __FP((struct lofig *apLofig, + char *conName)); + + extern loins_list *addloins_noSig __FP((lofig_list *apFig, + char *asIns, + lofig_list *apModel)); + + extern locon_list *addlosig_insCon __FP((loins_list *apIns, + char *asCon, + losig_list *apSig)); + + extern void checkLofig __FP((struct lofig *apLofig)); + extern void addfeed __FP((struct lofig *apLofig, + struct phfig *apPhfig)); + extern void delfeed __FP((struct lofig *apLofig)); + extern void copyUpCALU __FP((struct lofig *apLofig, + struct phfig *apPhfig, + long aExit)); + + extern struct eMVIA_s *addmvia __FP((struct eMVIA_s *apHead, + struct phvia *apVIA)); + extern struct eMVIA_s *getmvia __FP((struct eMVIA_s *apHead, + struct phvia *apVIA)); + extern struct eLoseg_s *addloseg __FP((struct eLoseg_s *apHead, + long aType, + void *apSegvia)); + extern struct eLoseg_s *delloseg __FP((struct eLoseg_s *apLoseg)); + extern struct tLoseg_s *gettloseg __FP((struct phfig *apPhfig)); + extern struct tLoseg_s *addtloseg __FP((struct phfig *apPhfig)); + extern struct authelem *gettlosegitem __FP((struct tLoseg_s *apTLoseg, + char *asKey)); + extern void freeloseg __FP((struct phfig *apPhfig)); + extern void phsegchain __FP((struct lofig *apLofig, + struct phfig *apPhfig)); + extern struct eLoseg_s *getloseglist __FP((struct phfig *apPhfig, + char *aName)); + extern void checklosegaccess __FP((struct phfig *apPhfig)); + extern void shiftphfig __FP((struct phfig *apPhfig, + long DX, + long DY)); + + + + +/* ---------------------------------------------------------------------- + * Module : "util_Power.c" + */ + + +# define F_POWER_COMPLETE 0x00000001 +# define C_POWER_ISNONE ((char)0) +# define C_POWER_ISVDD ((char)1) +# define C_POWER_ISVSS ((char)2) +# define C_POWER_VERTICAL ((char)1) +# define C_POWER_HORIZONTAL ((char)2) + +# define F_POWER_MERGE 0x00000001 + + + typedef struct ePow_s { + long flags; + long y; + long w; + long xMin; + long xMax; + long min; + long max; + char *Name; + char Type; + struct lInter_s *inter; + struct ePow_s *Next; + } ePow_t; + + + extern struct ePow_s *addPow __FP((struct ePow_s **applPow, + long aY, + long aW, + char *aName, + char aType, + char aDir)); + extern void freePow __FP((struct ePow_s *aplPow)); + extern struct ePow_s *getPow __FP((struct ePow_s *aplPow, long aY)); + extern void mergeXPow __FP((struct ePow_s *apPow, + long axMin, + long axMax, + long aW)); + extern struct ePow_s *buildPow __FP((struct phfig *apPhfig, + char aLayer, + char aDir, + char *asSuffix)); + extern void powToCon __FP(( struct phfig *apPhfig, + char aLayer, + char aDir, + struct ePow_s *aplPow, + long aFlags)); + + + + +/* ---------------------------------------------------------------------- + * Module : "util_RTU.c" + */ + + + extern void rtu __FP((struct phfig *aPhfig)); + + + + +/* ---------------------------------------------------------------------- + * Module : "util_Floorplan.c" + */ + +# define F_FLOOR_LAYERS_3 0x00000010 /* 16. */ +# define F_FLOOR_LAYERS_4 0x00000020 /* 16. */ +# define F_FLOOR_LAYERS_6 0x00000040 /* 32. */ +# define F_FLOOR_MARGIN 0x00000080 /* 64. */ +# define F_FLOOR_ROW_NUMBER 0x00000100 /* 128. */ +# define F_FLOOR_X_SIZE 0x00000200 /* 256. */ +# define F_FLOOR_Y_SIZE 0x00000400 /* 512. */ +# define F_FLOOR_ASPECT_RATIO 0x00000800 /* 1024. */ + +# define FLOOR_XY_EXPAND MBKSCALE(50) + + + extern void placeTerms __FP((struct lofig *apLofig, + struct phfig *apPhfig)); + extern struct phfig *makeFloorplan __FP((struct lofig *apLofig, + long aMargin, + long aXSize, + long aYSize, + double aAspectRatio, + long aPower, + long aFlags)); + extern void expandFloorplan __FP((struct phfig *apPhfig)); + extern void shrinkFloorplan __FP((struct phfig *apPhfig)); + extern void protectPowmid __FP((struct phfig *apPhfig)); + + + + +/* ---------------------------------------------------------------------- + * Module : "util_LEFDEF.c" + */ + + +# include "DEF_actions.h" + + + /* LEF/DEF terminal direction. */ +# define C_DIRECTION_NONE ((char)0) +# define C_DIRECTION_INPUT ((char)1) +# define C_DIRECTION_OUTPUT ((char)2) +# define C_DIRECTION_TRISTATE ((char)3) +# define C_DIRECTION_INOUT ((char)4) +# define C_DIRECTION_FEEDTHRU ((char)5) + +# define X_GRID 5 +# define Y_SLICE 50 +# define WIDTH_VDD 6 +# define WIDTH_VSS 6 +# define VIA_SIDE 2 +# define ALU1_SPACING 3 +# define MBK_X_GRID (X_GRID * SCALE_X) +# define MBK_Y_SLICE (Y_SLICE * SCALE_X) +# define MBK_WIDTH_VDD (WIDTH_VDD * SCALE_X) +# define MBK_WIDTH_VSS (WIDTH_VSS * SCALE_X) +# define MBK_VIA_SIDE (MBKSCALE (VIA_SIDE)) +# define MBK_ALU1_SPACING (MBKSCALE (ALU1_SPACING)) +# define DEF_X_GRID (X_GRID * DEF_UNITS_MICRONS) +# define DEF_Y_SLICE (Y_SLICE * DEF_UNITS_MICRONS) + + + extern long DEF_UNITS_MICRONS; + + + extern long DEF2MBK_length __FP((long aL)); + extern char *DEF2MBK_name __FP((char *aS)); + extern char DEF2MBK_transf __FP((double aO)); + extern char DEF2MBK_direction __FP((double aDEFdir)); + extern struct phref *DEF2MBK_row __FP((struct phfig *apPhfig, + char *aRowName, + char *aRowType, + long aOrient, + long aDoNumber, + long aByNumber, + long aStepX, + long aStepY, + long aX, + long aY)); + extern struct phref *DEF2MBK_track __FP((struct phfig *apPhfig, + char *aAxisName, + long aStart, + long aDoNumber, + long aStep, + char *asLayers, + long aX, + long aY)); + extern struct phref *DEF2MBK_blockage __FP((struct phfig *apPhfig, + long aXB1, + long aYB1, + long aWidth, + long aHeight)); + + extern long MBK2DEF_length __FP((long aL)); + extern char *MBK2DEF_name __FP((char *asLEF, char *asMBK)); + extern char MBK2DEF_direction __FP((char acDir)); + extern char MBK2DEF_transf __FP((char aO)); + extern void MBK2DEF_row __FP((struct phref *apPhref, + char **appRowName, + char **appRowType, + long *apOrient, + long *apDoNumber, + long *apByNumber, + long *apStepX, + long *apStepY, + long *apX, + long *apY)); + extern void MBK2DEF_track __FP((struct phref *apPhref, + char *apAxisName, + long *apStart, + long *apDoNumber, + long *apStep, + char **apsLayers, + long *apX, + long *apY)); + extern void MBK2DEF_blockage __FP((struct phref *apPhref, + long *apXB1, + long *apYB1, + long *apWidth, + long *apHeight)); + extern char MBK2DEF_locondir __FP((struct locon *apLocon)); + extern char *DEF_orient2a __FP((long aT)); + extern long DEF_a2orient __FP((char *aT)); + extern char *DEF_side2a __FP((char aSide)); + extern char *DEF_layer2a __FP((char aLayer)); + extern char *DEF_via2a __FP((char aType, + long aDX, + long aDY, + char *aViaName)); + + extern char BEH2DEF_direction __FP((char acDir)); + + +# endif diff --git a/alliance/src/sea/src/util_Floorplan.c b/alliance/src/sea/src/util_Floorplan.c new file mode 100644 index 00000000..fb9851cb --- /dev/null +++ b/alliance/src/sea/src/util_Floorplan.c @@ -0,0 +1,1207 @@ +/* + * $Id: util_Floorplan.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./util_Floorplan.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" +# include "debugoff.h" + + +/* ------------------------------------------------------------------ + * Local constants. + */ + +# define F_NO_OVERLAP ((long)(1<<0)) +# define F_OVERLAP ((long)(1<<1)) +# define F_I1_IN_I2 ((long)(1<<2)) +# define F_I2_IN_I1 ((long)(1<<3)) +# define F_SEG_EXCLUS ((long)(1<<0)) +# define F_SEG_INCLUS ((long)(1<<1)) +# define F_SEG_HALFOVER ((long)(1<<2)) +# define F_SEG_OVER ((long)(1<<3)) +# define F_TERM_XY ((long)(1<<0)) +# define F_TERM_LAYER ((long)(1<<1)) +# define F_TERM_SIDE ((long)(1<<2)) +# define F_TERM_USER ((long)(1<<3)) + +# define F_SIDE_FULL ((long)(1<<1)) + +# define SIDE_NORTH 0 +# define SIDE_SOUTH 1 +# define SIDE_EAST 2 +# define SIDE_WEST 3 +# define SIDE_ALL 4 + + +/* ------------------------------------------------------------------ + * Local structures. + */ + + typedef struct ulocon_s { + long flags; + } ulocon_t; + + typedef struct term_s { + long flags; + char *name; + char layer; + long XY; + struct term_s *next; + } term_t; + + + typedef struct side_s { + char orient; + char layer; + long flags; + long x; + long y; + long length; + long nbTerm; + long maxTerm; + struct term_s *lTerm; + } side_t; + + +/* ------------------------------------------------------------------ + * Local variables. + */ + + static char routingLayers3[256] = "l_alu1.l_alu2.l_alu3."; + static char routingLayers4[256] = + "l_alu1.l_alu2.l_alu3.l_alu4."; + static char routingLayers6[256] = + "l_alu1.l_alu2.l_alu3.l_alu4.l_alu5.l_alu6."; + static long LV_dupTerm; + static long LV_loTerm; + + +/* ------------------------------------------------------------------ + * Local macros. + */ + +# define SNAPGRID(x) ((x) - ((x) % MBK_X_GRID)) + + +/* ---------------------------------------------------------------------- + * Local functions declarations. + */ + + static struct term_s *newTerm __FP((struct term_s *apHead, + long aFlags, + char *aName, + char aLayer, + long aXY)); + static struct term_s *freeTerm __FP((struct term_s *apTerm)); + static struct ulocon_s *getUlocon __FP((struct locon *apLocon)); + static struct ulocon_s *newUlocon __FP((struct locon *apLocon)); + static void freeUlocon __FP((struct locon *apLocon)); + static void linkTerm __FP((struct locon *apLocon, + long aFlags)); + static void unlinkTerm __FP((struct locon *apLocon)); + static struct side_s *newSide __FP((char aOrient, + char aLayer, + long aX, + long aY, + long aLength)); + static void freeSide __FP((struct side_s *apSide)); + static struct side_s *buildSide __FP((struct phfig *apPhfig, + struct lofig *apLofig, + char aOrient, + char aLayer)); + static long countDupTerms __FP((struct phfig *apPhfig)); + static long addLoconUinfo __FP((struct lofig *apLofig)); + static void freeLoconUinfo __FP((struct lofig *apLofig)); + static long computeArea __FP((struct lofig *apLofig)); +# if 0 + static long intervalRel __FP((long aI1_min, + long aI1_max, + long aI2_min, + long aI2_max)); + static long segInArea __FP((struct phseg *aPhseg, + long aX1, + long aY1, + long aX2, + long aY2)); +# endif + + +/* + * /--------------------------------------------------------------------\ + * | Functions Definitions | + * \--------------------------------------------------------------------/ + */ + +/* ---------------------------------------------------------------------- + * Function : "newTerm()". + */ + +static struct term_s *newTerm (apHead, aFlags, aName, aLayer, aXY) + struct term_s *apHead; + long aFlags; + char *aName; + char aLayer; + long aXY; +{ + struct term_s *pTerm; + + + pTerm = (struct term_s*)mbkalloc (sizeof (struct term_s)); + + pTerm->flags = aFlags; + pTerm->name = aName; + pTerm->layer = aLayer; + pTerm->XY = aXY; + pTerm->next = apHead; + + return (pTerm); +} + + +/* ---------------------------------------------------------------------- + * Function : "freeTerm()". + */ + +static struct term_s *freeTerm (apTerm) + struct term_s *apTerm; +{ + struct term_s *pNext; + + + pNext = apTerm->next; + + mbkfree (apTerm); + + return (pNext); +} + + +/* ---------------------------------------------------------------------- + * Function : "getUlocon()". + */ + +static struct ulocon_s *getUlocon (apLocon) + struct locon *apLocon; +{ + struct ptype *pType; + + + if (!(pType = getptype (apLocon->USER, PTYPE_ULOCON))) return (NULL); + + return ((struct ulocon_s*)pType->DATA); +} + + +/* ---------------------------------------------------------------------- + * Function : "newUlocon()". + */ + +static struct ulocon_s *newUlocon (apLocon) + struct locon *apLocon; +{ + struct ptype *pType; + struct ulocon_s *pUlocon; + + + if (!(pUlocon = getUlocon (apLocon))) { + pUlocon = (struct ulocon_s*)mbkalloc (sizeof (struct ulocon_s)); + + pUlocon->flags = 0L; + + apLocon->USER = addptype (apLocon->USER, PTYPE_ULOCON, (void*)pUlocon); + + pType = apLocon->USER; + } + + + return (pUlocon); +} + + +/* ---------------------------------------------------------------------- + * Function : "freeUlocon()". + */ + +static void freeUlocon (apLocon) + struct locon *apLocon; +{ + struct ptype *pType; + + + if ((pType = getptype (apLocon->USER, PTYPE_ULOCON))) { + mbkfree (pType->DATA); + + apLocon->USER = delptype (apLocon->USER, PTYPE_ULOCON); + } +} + + +/* ---------------------------------------------------------------------- + * Function : "linkTerm()". + */ + +static void linkTerm (apLocon, aFlags) + struct locon *apLocon; + long aFlags; +{ + struct ulocon_s *pUlocon; + + + if (!(pUlocon = getUlocon (apLocon))) + pUlocon = newUlocon (apLocon); + + pUlocon->flags = aFlags; +} + + +/* ---------------------------------------------------------------------- + * Function : "unlinkTerm()". + */ + +static void unlinkTerm (apLocon) + struct locon *apLocon; +{ + freeUlocon (apLocon); +} + + +/* ---------------------------------------------------------------------- + * Function : "newSide()". + */ + +static struct side_s *newSide (aOrient, aLayer, aX, aY, aLength) + char aOrient; + char aLayer; + long aX; + long aY; + long aLength; +{ + struct side_s *pSide; + + + pSide = (struct side_s*)mbkalloc (sizeof (struct side_s)); + + pSide->nbTerm = 0; + pSide->maxTerm = 0; + pSide->flags = 0; + pSide->lTerm = NULL; + pSide->orient = aOrient; + pSide->layer = aLayer; + pSide->x = aX; + pSide->y = aY; + pSide->length = aLength; + + return (pSide); +} + + +/* ---------------------------------------------------------------------- + * Function : "freeSide()". + */ + +static void freeSide (apSide) + struct side_s *apSide; +{ + struct term_s *pTerm; + + + for (pTerm = apSide->lTerm; pTerm != NULL; pTerm = freeTerm (pTerm)); + + mbkfree (apSide); +} + + +/* ---------------------------------------------------------------------- + * Function : "buildSide()". + */ + +static struct side_s *buildSide (apPhfig, apLofig, aOrient, aLayer) + struct phfig *apPhfig; + struct lofig *apLofig; + char aOrient; + char aLayer; +{ + struct side_s *pSide; + struct phcon *pPhcon; + long XSIDE, YSIDE, sideLength; + + + switch (aOrient) { + case WEST: + XSIDE = apPhfig->XAB1; + YSIDE = apPhfig->YAB1; + sideLength = apPhfig->YAB2 - apPhfig->YAB1; + break; + case EAST: + XSIDE = apPhfig->XAB2; + YSIDE = apPhfig->YAB1; + sideLength = apPhfig->YAB2 - apPhfig->YAB1; + break; + case NORTH: + XSIDE = apPhfig->XAB1; + YSIDE = apPhfig->YAB2; + sideLength = apPhfig->XAB2 - apPhfig->XAB1; + break; + default: + case SOUTH: + XSIDE = apPhfig->XAB1; + YSIDE = apPhfig->YAB1; + sideLength = apPhfig->XAB2 - apPhfig->XAB1; + break; + } + + + pSide = newSide (aOrient, aLayer, XSIDE, YSIDE, sideLength); + + for (pPhcon = apPhfig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) { + /* Checking terminal orientation. */ + if (pPhcon->ORIENT == aOrient) { + switch (aOrient) { + case EAST: + case WEST: + if (XSIDE != pPhcon->XCON) { + eprinth ("buildSide"); + eprintf ("\n East/west terminal %s at (%ld,%ld) is not on", + pPhcon->NAME, + pPhcon->XCON, + pPhcon->YCON); + eprintf ("\n the abutment-box.\n"); + EXIT (1); + } + + /* Adding the terminal to the side's list. */ + pSide->nbTerm++; + pSide->lTerm = newTerm (pSide->lTerm, + F_TERM_XY|F_TERM_LAYER|F_TERM_USER, + pPhcon->NAME, + pPhcon->LAYER, + pPhcon->YCON); + break; + case NORTH: + default: + case SOUTH: + if (YSIDE != pPhcon->YCON) { + eprinth ("buildSide"); + eprintf ("\n North/south terminal %s at (%ld,%ld) is not on", + pPhcon->NAME, + pPhcon->XCON, + pPhcon->YCON); + eprintf ("\n the abutment-box.\n"); + EXIT (1); + } + + /* Adding the terminal to the side's list. */ + pSide->nbTerm++; + pSide->lTerm = newTerm (pSide->lTerm, + F_TERM_XY|F_TERM_LAYER|F_TERM_USER, + pPhcon->NAME, + pPhcon->LAYER, + pPhcon->XCON); + break; + } + + linkTerm (getlocon (apLofig, pPhcon->NAME), + F_TERM_XY|F_TERM_LAYER|F_TERM_SIDE); + } + } + + return (pSide); +} + + +/* ---------------------------------------------------------------------- + * Function : "sortSide()". + */ + +static void sortSide(apSide) + struct side_s *apSide; +{ + struct term_s *pTerm; + char *tFilled; + long i, spacing, sideOrig; + + + tFilled = (char*)mbkalloc (sizeof (char) * apSide->nbTerm); + + switch (apSide->orient) { + case EAST: + case WEST: + sideOrig = apSide->y; break; + case NORTH: + case SOUTH: + default: + sideOrig = apSide->x; break; + } + + spacing = apSide->length / apSide->nbTerm; + for (i = 0; i < apSide->nbTerm; i++) tFilled[i] = '\0'; + + for (pTerm = apSide->lTerm; pTerm != NULL; pTerm = pTerm->next) { + if (pTerm->flags & F_TERM_XY) { + tFilled[(pTerm->XY - sideOrig) / spacing ] = '\1'; + } + } + + __DBG( fprintf (stderr, "spacing := %ld\n", spacing); ) + + i = 0; + for (pTerm = apSide->lTerm; pTerm != NULL; pTerm = pTerm->next) { + __DBG( fprintf (stderr, "i := %ld\n", i); ) + + if (!(pTerm->flags & F_TERM_XY)) { + pTerm->XY = sideOrig + SNAPGRID((spacing * i) + (spacing >> 1)); + pTerm->layer = apSide->layer; + + __DBG( fprintf (stderr, "pTerm->XY := %ld\n", pTerm->XY); ) + } + + i++; + } +} + + +/* ---------------------------------------------------------------------- + * Function : "countDupTerms()". + */ + +static long countDupTerms (apPhfig) + struct phfig *apPhfig; +{ + struct phcon *pPhcon; + struct authtable *htCon; + struct authelem *pElem; + + + htCon = createauthtable (1024); + + /* Find the number of duplicated terminals. */ + for (pPhcon = apPhfig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) { + pElem = searchauthelem (htCon, pPhcon->NAME); + + if (!pElem) { + pElem = addauthelem (htCon, pPhcon->NAME, -1); + } + + pElem->VALUE++; + } + + + LV_dupTerm = 0; + + /* Make the sum. */ + for (pPhcon = apPhfig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) { + pElem = searchauthelem (htCon, pPhcon->NAME); + + LV_dupTerm += pElem->VALUE; + + /* Do not count twice duplicated terminals... */ + pElem->VALUE = 0; + } + + destroyauthtable (htCon); + + + return (LV_dupTerm); +} + + +/* ---------------------------------------------------------------------- + * Function : "addLoconUinfo()". + */ + +static long addLoconUinfo (apLofig) + struct lofig *apLofig; +{ + struct locon *pLocon; + + + LV_loTerm = 0; + + + for (pLocon = apLofig->LOCON; pLocon != NULL; pLocon = pLocon->NEXT) { + LV_loTerm++; + + linkTerm (pLocon, 0); + } + + return (LV_loTerm); +} + + +/* ---------------------------------------------------------------------- + * Function : "freeLoconUinfo()". + */ + +static void freeLoconUinfo (apLofig) + struct lofig *apLofig; +{ + struct locon *pLocon; + + + for (pLocon = apLofig->LOCON; pLocon != NULL; pLocon = pLocon->NEXT) { + unlinkTerm (pLocon); + } +} + + +/* ---------------------------------------------------------------------- + * Function : "nextFreeLocon()". + */ + +static struct locon *nextFreeLocon (apLocon) + struct locon *apLocon; +{ + struct ulocon_s *pUlocon; + struct locon *pLocon; + + + for (pLocon = apLocon; pLocon != NULL; pLocon = pLocon->NEXT) { + pUlocon = getUlocon (pLocon); + + if (!(pUlocon->flags & F_TERM_SIDE)) return (pLocon); + } + + return (NULL); +} + + +/* ---------------------------------------------------------------------- + * Function : "placeTerms()". + */ + +extern void placeTerms (apLofig, apPhfig) + struct lofig *apLofig; + struct phfig *apPhfig; +{ + struct side_s *tSide[4]; + struct term_s *pTerm; + struct locon *pLocon; + long iSide; + long spaceTerm, newSpaceTerm, sideSpaceTerm; + long nbPhterm , newNbPhterm; + long nbPlacedTerm; + long flagLoop; + long XCON, YCON; + + + addLoconUinfo (apLofig); + countDupTerms (apPhfig); + + tSide[SIDE_NORTH] = buildSide (apPhfig, apLofig, NORTH, ALU3); + tSide[SIDE_SOUTH] = buildSide (apPhfig, apLofig, SOUTH, ALU3); + tSide[SIDE_EAST] = buildSide (apPhfig, apLofig, EAST , ALU2); + tSide[SIDE_WEST] = buildSide (apPhfig, apLofig, WEST , ALU2); + + + /* Side allocation for free terminals. */ + + nbPhterm = LV_loTerm + LV_dupTerm; + spaceTerm = 0; + nbPlacedTerm = 0; + + for (iSide = 0; iSide < SIDE_ALL; iSide++) { + spaceTerm += tSide[iSide]->length; + nbPlacedTerm += tSide[iSide]->nbTerm; + } + + spaceTerm /= (nbPhterm + 1); + + __DBG( fprintf (stderr, "spaceTerm := %ld\n", spaceTerm); ) + __DBG( fprintf (stderr, "nbPhterm := %ld\n", nbPhterm ); ) + + + if (nbPlacedTerm < nbPhterm) { + /* Find sides with free space for terminals. */ + for (flagLoop = TRUE; flagLoop; ) { + flagLoop = FALSE; + + newSpaceTerm = 0; + newNbPhterm = LV_loTerm + LV_dupTerm; + + for (iSide = 0; iSide < SIDE_ALL; iSide++) { + if (tSide[iSide]->flags & F_SIDE_FULL) { + newNbPhterm -= tSide[iSide]->nbTerm; + } else { + + sideSpaceTerm = tSide[iSide]->length / (tSide[iSide]->nbTerm + 1); + __DBG( fprintf (stderr, "sideSpaceTerm := %ld\n", sideSpaceTerm); ) + + if (sideSpaceTerm <= spaceTerm) { + __DBG( fprintf (stderr, "side %ld overloaded\n", iSide); ) + /* This side is overloaded : skip it. */ + flagLoop = TRUE; + + tSide[iSide]->flags |= F_SIDE_FULL; + tSide[iSide]->maxTerm = tSide[iSide]->nbTerm; + newNbPhterm -= tSide[iSide]->nbTerm; + } else { + newSpaceTerm += sideSpaceTerm; + tSide[iSide]->maxTerm = tSide[iSide]->length / spaceTerm; + __DBG( fprintf (stderr, + "tSide[%ld]->maxTerm := %ld\n", + iSide, + tSide[iSide]->maxTerm); ) + } + } + } /* End of 'for(iSide ...)'. */ + + spaceTerm = newSpaceTerm / (newNbPhterm + 1); + + __DBG( fprintf (stderr, "spaceTerm := %ld\n", spaceTerm); ) + } /* End of 'for(flagLoop... )'. */ + } + + + /* Dispatch remaining terminals on non-overloaded sides. */ + iSide = 0; + + for (pLocon = nextFreeLocon (apLofig->LOCON); + pLocon != NULL; pLocon = nextFreeLocon (pLocon->NEXT)) { + while (tSide[iSide]->nbTerm >= tSide[iSide]->maxTerm) { + if (iSide >= SIDE_ALL) { + eprinth ("placeTerms"); + eprintf ("\n No more sides to place terminals"); + eprintf (" (this is a bug)\n\n"); + EXIT (1); + } + + iSide++; + } + + tSide[iSide]->nbTerm++; + tSide[iSide]->lTerm = newTerm (tSide[iSide]->lTerm, + 0, + pLocon->NAME, + 0, + 0); + + linkTerm (pLocon, F_TERM_SIDE); + } + + + /* Sets the positions on all sides. */ + for (iSide = 0; iSide < SIDE_ALL; iSide++) { + __DBG (fprintf (stderr, "sortSide(%ld)\n", iSide); ) + sortSide (tSide[iSide]); + } + + + /* Add the physical terminals. */ + for (iSide = 0; iSide < SIDE_ALL; iSide++) { + for (pTerm = tSide[iSide]->lTerm; pTerm != NULL; pTerm = pTerm->next) { + switch (tSide[iSide]->orient) { + case NORTH: + case SOUTH: + default: + XCON = pTerm->XY; + YCON = tSide[iSide]->y; + break; + case EAST: + case WEST: + XCON = tSide[iSide]->x; + YCON = pTerm->XY; + break; + } + + addphcon (apPhfig, + tSide[iSide]->orient, + pTerm->name, + XCON, + YCON, + pTerm->layer, + MBKSCALE(2)); + } + } + + + + /* Free all the sides structures. */ + for (iSide = 0; iSide < SIDE_ALL; iSide++) freeSide (tSide[iSide]); + + freeLoconUinfo (apLofig); +} + + +/* ---------------------------------------------------------------------- + * Function : "computeArea()". + */ + +static long computeArea(apLofig) + struct lofig *apLofig; +{ + struct loins* pLoins; + struct phfig* pModel; + long area; + long AB_width, AB_height; + + + area = 0L; + + for (pLoins = apLofig->LOINS; pLoins != NULL; pLoins = pLoins->NEXT) { + pModel = getphfig (pLoins->FIGNAME, 'P'); + + AB_width = pModel->XAB2 - pModel->XAB1; + AB_height = pModel->YAB2 - pModel->YAB1; + + + if (AB_width <= 0) { + eprinth (NULL); + eprintf ( + "Negative or null width (%ld) for abutment box of \"%s\".\n", + AB_width, pModel->NAME); + EXIT (1); + } + + if (AB_height <= 0) { + eprinth (NULL); + eprintf ( + "Negative or null height (%ld) for abutment box of \"%s\".\n", + AB_height, pModel->NAME); + EXIT (1); + } + + if (AB_width % MBK_X_GRID) { + eprinth (NULL); + eprintf ( + "Unpitched width (%ld) for abutment box of \"%s\".\n", + AB_width, pModel->NAME); + EXIT (1); + } + + if (AB_height % MBK_Y_SLICE) { + eprinth (NULL); + eprintf ( + "Unpitched height (%ld) for abutment box of \"%s\".\n", + AB_height, pModel->NAME); + EXIT (1); + } + + + AB_width = AB_width / MBK_X_GRID; + AB_height = AB_height / MBK_Y_SLICE; + + area += AB_width * AB_height; + } + + + return (area); +} + + +/* ---------------------------------------------------------------------- + * Function : "makeFloorplan()". + */ + +extern struct phfig *makeFloorplan(apLofig, + aMargin, + aXSize, + aYSize, + aAspectRatio, + aPower, + aFlags) + struct lofig *apLofig; + long aMargin; + long aXSize; + long aYSize; + double aAspectRatio; + long aPower; + long aFlags; +{ + struct phfig *pPhfig; + long specCount, i; + long area; + long xSize, ySize; + long XAB1, YAB1, XAB2, YAB2; + char row_name[1024], row_type[1024]; + char *routingLayers; + + + specCount = (aFlags & F_FLOOR_X_SIZE) ? 1 : 0; + specCount += (aFlags & F_FLOOR_Y_SIZE) ? 1 : 0; + specCount += (aFlags & F_FLOOR_ASPECT_RATIO) ? 1 : 0; + + if (specCount != 1) { + errMBK ("makeFloorplan"); + eprintf ("\n One, and only one argument among aXSize, aYSize and"); + eprintf ( " aAspectRatio must\n be non zero.\n"); + EXIT (1); + } + + pPhfig = addphfig (apLofig->NAME); + + area = computeArea (apLofig); + area = (long)((1.0 + (double)aMargin / 100.0) * (double)area); + + /* Shut up GCC. */ + xSize = 0; + ySize = 0; + + if (aFlags & F_FLOOR_X_SIZE) { + xSize = aXSize; + ySize = area / (xSize - 7 * aPower) + + ((area % (xSize - 7 * aPower)) ? 1 : 0); + } + + if (aFlags & F_FLOOR_Y_SIZE) { + ySize = aYSize; + xSize = (7 * aPower) + (area / aYSize) + ((area / aYSize) ? 1 : 0); + } + + if (aFlags & F_FLOOR_ASPECT_RATIO) { + double x, r, b, xy; + + xy = (double)(Y_SLICE / X_GRID); + + b = ((double)(7 * aPower)) / xy; + x = (b + sqrt (pow (b, 2.0) + 4 * xy * (double)(area) * aAspectRatio)) + / (2 * xy * aAspectRatio); + + ySize = (long)floor (x * aAspectRatio); + + /* Compute missing area (as ySize is rounded down). + * The unit the number of horizontal sites. + */ + r = ((double)(area + 7 * aPower * ySize) - pow ((double)ySize, 2.0) * xy) + / (double)(ySize); + + xSize = ((long)ceil ((double)ySize * xy + r)); + } + + + XAB1 = 0L; + YAB1 = 0L; + XAB2 = xSize * MBK_X_GRID; + YAB2 = ySize * MBK_Y_SLICE; + + + /* Build the floorplan. */ + + /* The Abutment-box. */ + defab (pPhfig, XAB1, YAB1, XAB2, YAB2); + + /* The row matrix. */ + strcpy (row_type, "core"); + for (i = 0; i < ySize; i++) { + sprintf (row_name, "row_%ld", i); + + DEF2MBK_row (pPhfig, + row_name, + row_type, + (i % 2) ? DEF_FS : DEF_N, + xSize, + 1L, + DEF_X_GRID, + DEF_Y_SLICE, + XAB1, + YAB1 + i * MBK_Y_SLICE); + } + + /* The tracks matrix. */ + routingLayers = routingLayers6; + + if (aFlags & F_FLOOR_LAYERS_3) { + routingLayers = routingLayers3; + } + + if (aFlags & F_FLOOR_LAYERS_4) { + routingLayers = routingLayers4; + } + + /* Horizontal tracks. */ + DEF2MBK_track (pPhfig, + "Y", + MBK2DEF_length (YAB1 + MBK_X_GRID), + ySize * (Y_SLICE / X_GRID) - 1, + DEF_X_GRID, + routingLayers, + XAB1, + YAB1 + MBK_X_GRID); + + /* Vertical tracks. */ + DEF2MBK_track (pPhfig, + "X", + MBK2DEF_length (XAB1 + MBK_X_GRID), + xSize - 1, + DEF_X_GRID, + routingLayers, + XAB1 + MBK_X_GRID, + YAB1); + + + return (pPhfig); +} + + +/* ---------------------------------------------------------------------- + * Function : "expandFloorplan()". + */ + +extern void expandFloorplan(apPhfig) + struct phfig *apPhfig; +{ + struct phseg *pPhseg; + struct phcon *pPhcon; + long XAB1, YAB1, XAB2, YAB2; + + + XAB1 = apPhfig->XAB1; + YAB1 = apPhfig->YAB1; + XAB2 = apPhfig->XAB2; + YAB2 = apPhfig->YAB2; + + + apPhfig->XAB1 -= FLOOR_XY_EXPAND; + apPhfig->YAB1 -= FLOOR_XY_EXPAND; + apPhfig->XAB2 += FLOOR_XY_EXPAND; + apPhfig->YAB2 += FLOOR_XY_EXPAND; + + + /* Move terminals to the new AB. */ + for (pPhcon = apPhfig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) { + if (pPhcon->XCON == XAB1) pPhcon->XCON = apPhfig->XAB1; + if (pPhcon->XCON == XAB2) pPhcon->XCON = apPhfig->XAB2; + if (pPhcon->YCON == YAB1) pPhcon->YCON = apPhfig->YAB1; + if (pPhcon->YCON == YAB2) pPhcon->YCON = apPhfig->YAB2; + } + + + /* Shrink segments to fit in the new AB. */ + for (pPhseg = apPhfig->PHSEG; pPhseg != NULL; pPhseg = pPhseg->NEXT) { + if (pPhseg->X1 == XAB1) pPhseg->X1 = apPhfig->XAB1; + if (pPhseg->X2 == XAB2) pPhseg->X2 = apPhfig->XAB2; + if (pPhseg->Y1 == YAB1) pPhseg->Y1 = apPhfig->YAB1; + if (pPhseg->Y2 == YAB2) pPhseg->Y2 = apPhfig->YAB2; + } + + +# if 0 + DEF2MBK_blockage (apPhfig, + MBK2DEF_length (apPhfig->XAB1), + MBK2DEF_length (apPhfig->YAB1), + MBK2DEF_length (FLOOR_XY_EXPAND), + MBK2DEF_length (FLOOR_XY_EXPAND) + ); + + DEF2MBK_blockage (apPhfig, + MBK2DEF_length (apPhfig->XAB1), + MBK2DEF_length (apPhfig->YAB2 - FLOOR_XY_EXPAND), + MBK2DEF_length (FLOOR_XY_EXPAND), + MBK2DEF_length (FLOOR_XY_EXPAND) + ); + + DEF2MBK_blockage (apPhfig, + MBK2DEF_length (apPhfig->XAB2 - FLOOR_XY_EXPAND), + MBK2DEF_length (apPhfig->YAB1), + MBK2DEF_length (FLOOR_XY_EXPAND), + MBK2DEF_length (FLOOR_XY_EXPAND) + ); + + DEF2MBK_blockage (apPhfig, + MBK2DEF_length (apPhfig->XAB2 - FLOOR_XY_EXPAND), + MBK2DEF_length (apPhfig->YAB2 - FLOOR_XY_EXPAND), + MBK2DEF_length (FLOOR_XY_EXPAND), + MBK2DEF_length (FLOOR_XY_EXPAND) + ); +# endif +} + + +# if 0 +/* ---------------------------------------------------------------------- + * Function : "intervalRel()". + */ + +static long intervalRel(aI1_min, aI1_max, aI2_min, aI2_max) + long aI1_min, aI1_max, aI2_min, aI2_max; +{ + long flag; + + + if (aI1_min > aI1_max) { + errMBK ("intervalRel"); + eprintf (" I1_min(%ld) > I1_max(%ld) !\n", aI1_min, aI1_max); + EXIT (1); + } + if (aI2_min > aI2_max) { + errMBK ("intervalRel"); + eprintf (" I2_min(%ld) > I2_max(%ld) !\n", aI2_min, aI2_max); + EXIT (1); + } + + + flag = 2; + + if ((aI1_min < aI2_min) || (aI1_min > aI2_max)) flag--; + if ((aI1_max < aI2_min) || (aI1_max > aI2_max)) flag--; + if ((aI1_min < aI2_min) && (aI1_max > aI2_max)) flag = 3; + + + switch (flag) { + default: + case 3: flag = F_I2_IN_I1; break; + case 2: flag = F_I1_IN_I2; break; + case 1: flag = F_OVERLAP; break; + case 0: flag = F_NO_OVERLAP; break; + } + + return (flag); +} + + +/* ---------------------------------------------------------------------- + * Function : "segInArea()". + */ + +static long segInArea(aPhseg, aX1, aY1, aX2, aY2) + struct phseg *aPhseg; + long aX1, aY1, aX2, aY2; +{ + long flagX, flagY; + + + if (aX1 > aX2) { + errMBK ("segInArea"); + eprintf ("Bad area X1(%ld) > X2(%ld) !\n", aX1, aX2); + EXIT (1); + } + if (aY1 > aY2) { + errMBK ("segInArea"); + eprintf ("Bad area Y1(%ld) > Y2(%ld) !\n", aY1, aY2); + EXIT (1); + } + + + flagX = intervalRel (aPhseg->X1, aPhseg->X2, aX1, aX2); + flagY = intervalRel (aPhseg->Y1, aPhseg->Y2, aY1, aY2); + + + if ((flagX == F_NO_OVERLAP) || (flagY == F_NO_OVERLAP)) + return (F_SEG_EXCLUS); + + if ((flagX == F_I1_IN_I2) && (flagY == F_I1_IN_I2)) + return (F_SEG_INCLUS); + + if ((flagX == F_I2_IN_I1) && (flagY == F_I2_IN_I1)) + return (F_SEG_HALFOVER); + + return (F_SEG_OVER); +} +# endif + + +/* ---------------------------------------------------------------------- + * Function : "shrinkFloorplan()". + */ + +extern void shrinkFloorplan(apPhfig) + struct phfig *apPhfig; +{ + struct phseg *pPhseg; + struct phcon *pPhcon; + struct phref *pPhref; + long XAB1, YAB1, XAB2, YAB2; + + + XAB1 = apPhfig->XAB1; + YAB1 = apPhfig->YAB1; + XAB2 = apPhfig->XAB2; + YAB2 = apPhfig->YAB2; + + /* Shrink the abutment-box. */ + apPhfig->XAB1 += FLOOR_XY_EXPAND; + apPhfig->YAB1 += FLOOR_XY_EXPAND; + apPhfig->XAB2 -= FLOOR_XY_EXPAND; + apPhfig->YAB2 -= FLOOR_XY_EXPAND; + + + /* Move terminals to the new AB. */ + for (pPhcon = apPhfig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) { + if (pPhcon->XCON == XAB1) pPhcon->XCON = apPhfig->XAB1; + if (pPhcon->XCON == XAB2) pPhcon->XCON = apPhfig->XAB2; + if (pPhcon->YCON == YAB1) pPhcon->YCON = apPhfig->YAB1; + if (pPhcon->YCON == YAB2) pPhcon->YCON = apPhfig->YAB2; + } + + + /* Shrink segments to fit in the new AB. */ + for (pPhseg = apPhfig->PHSEG; pPhseg != NULL; pPhseg = pPhseg->NEXT) { + if (pPhseg->X1 == XAB1) pPhseg->X1 = apPhfig->XAB1; + if (pPhseg->X2 == XAB2) pPhseg->X2 = apPhfig->XAB2; + if (pPhseg->Y1 == YAB1) pPhseg->Y1 = apPhfig->YAB1; + if (pPhseg->Y2 == YAB2) pPhseg->Y2 = apPhfig->YAB2; + } + + + /* Move references to the new AB. */ + for (pPhref = apPhfig->PHREF; pPhref != NULL; pPhref = pPhref->NEXT) { + if (pPhref->XREF == XAB1) pPhref->XREF = apPhfig->XAB1; + if (pPhref->XREF == XAB2) pPhref->XREF = apPhfig->XAB2; + if (pPhref->YREF == YAB1) pPhref->YREF = apPhfig->YAB1; + if (pPhref->YREF == YAB2) pPhref->YREF = apPhfig->YAB2; + } +} + + +/* ---------------------------------------------------------------------- + * Function : "protectPowmid()". + */ + +extern void protectPowmid(apPhfig) + struct phfig *apPhfig; +{ +# if 0 + struct phins *pIns; +# endif + struct phfig *pModel; + char *powmidName; + long width, height, expand; + + + expand = FLOOR_XY_EXPAND; + + + powmidName = namealloc ("powmid_x0"); + + pModel = getphfig ("powmid_x0", 'A'); + width = pModel->XAB2 - pModel->XAB1; + height = pModel->YAB2 - pModel->YAB1; + +# if 0 + for (pIns = apPhfig->PHINS; pIns != NULL; pIns = pIns->NEXT) { + if (pIns->FIGNAME == powmidName) { + if (pIns->YINS == apPhfig->YAB1 + expand) { + DEF2MBK_blockage (apPhfig, + MBK2DEF_length (pIns->XINS), + MBK2DEF_length (apPhfig->YAB1), + MBK2DEF_length (width), + MBK2DEF_length ((MBK_X_GRID << 1) + expand) + ); + } + + if (pIns->YINS + height == apPhfig->YAB2 - expand) { + DEF2MBK_blockage (apPhfig, + MBK2DEF_length (pIns->XINS), + MBK2DEF_length (apPhfig->YAB2 + - (MBK_X_GRID << 1) - expand), + MBK2DEF_length (width), + MBK2DEF_length ((MBK_X_GRID << 1) + expand) + ); + } + } + } +# endif +} diff --git a/alliance/src/sea/src/util_Inter.c b/alliance/src/sea/src/util_Inter.c new file mode 100644 index 00000000..880b6236 --- /dev/null +++ b/alliance/src/sea/src/util_Inter.c @@ -0,0 +1,296 @@ + +/* + * $Id: util_Inter.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./util_Inter.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" +# include "debugoff.h" + + + +/* ------------------------------------------------------------------ + * Local constants. + */ + +# define SHIFT_MAX 8 +# define F_MIN_IN 0x00000001 +# define F_MIN_LOWER 0x00000002 +# define F_MIN_GREATER 0x00000004 +# define F_MAX_IN ((F_MIN_IN) << SHIFT_MAX) +# define F_MAX_LOWER ((F_MIN_LOWER) << SHIFT_MAX) +# define F_MAX_GREATER ((F_MIN_GREATER) << SHIFT_MAX) +# define C_INTER_LOWER (F_MIN_LOWER | F_MAX_LOWER ) +# define C_INTER_CROSS_MIN (F_MIN_LOWER | F_MAX_IN ) +# define C_INTER_IN (F_MIN_IN | F_MAX_IN ) +# define C_INTER_CROSS_MAX (F_MIN_IN | F_MAX_GREATER) +# define C_INTER_GREATER (F_MIN_GREATER | F_MAX_GREATER) +# define C_INTER_OUT (F_MIN_LOWER | F_MAX_GREATER) + + +# define INBOUNDS_INTER(i,v) (inbounds ((i)->min, (i)->max, (v))) + + +/* ------------------------------------------------------------------ + * Local functions declarations. + */ + +static long inbounds __FP((long aMin, long aMax, long aValue)); +static struct eInter_s *alloceinter __FP((long aMin, long aMax)); +static void freeeinter __FP((struct eInter_s *apInter)); +static long cmpeinter __FP((struct eInter_s *apInterA, + struct eInter_s *apInterB)); + + + +/* + * /----------------------------------------------------------------\ + * | Functions Definitions | + * \----------------------------------------------------------------/ + */ + +/* ------------------------------------------------------------------ + * Function : "inbounds()". + */ + +static long inbounds (aMin, aMax, aValue) + long aMin, aMax, aValue; +{ + if ((aValue >= aMin) && (aValue <= aMax)) return (F_MIN_IN); + + if (aValue < aMin) return (F_MIN_LOWER); + + return (F_MIN_GREATER); +} + + +/* ------------------------------------------------------------------ + * Function : "alloceinter()". + */ + +static struct eInter_s *alloceinter (aMin, aMax) + long aMin, aMax; +{ + struct eInter_s *newInter; + + + if (!(newInter = (struct eInter_s*)mbkalloc(sizeof (struct eInter_s)))) { + eprinth ("util_Inter.c"); + eprintf ("Not enough memory to allcate an interval element.\n"); + EXIT (1); + } + + newInter->min = aMin; + newInter->max = aMax; + newInter->next = NULL; + + return (newInter); +} + + +/* ------------------------------------------------------------------ + * Function : "freeeinter()". + */ + +static void freeeinter (apInter) + struct eInter_s *apInter; +{ + mbkfree ((void*)apInter); +} + + +/* ------------------------------------------------------------------ + * Function : "cmpeinter()". + */ + +static long cmpeinter (apInterA, apInterB) + struct eInter_s *apInterA, *apInterB; +{ + long state; + + + state = INBOUNDS_INTER(apInterA, apInterB->min); + state |= INBOUNDS_INTER(apInterA, apInterB->max) << SHIFT_MAX; + + return (state); +} + + +/* ------------------------------------------------------------------ + * Function : "allocinter()". + */ + +static struct lInter_s *allocinter () +{ + struct lInter_s *newInter; + + + if (!(newInter = (struct lInter_s*)mbkalloc(sizeof (struct lInter_s)))) { + eprinth ("util_Inter.c"); + eprintf ("Not enough memory to allocate an interval object.\n"); + EXIT (1); + } + + newInter->min = 0; + newInter->max = 0; + newInter->len = 0; + newInter->l = NULL; + + return (newInter); +} + + +/* ------------------------------------------------------------------ + * Function : "printinter()". + */ + +extern void printinter (apInter) + struct lInter_s *apInter; +{ + struct eInter_s *pInter; + + + fflush (stderr); + fprintf (stdout, " o Interval set : (min = %ld, max = %ld, len = %ld)\n", + apInter->min, + apInter->max, + apInter->len); + fflush (stdout); + + for (pInter = apInter->l; pInter != NULL; pInter = pInter->next) { + fprintf (stdout, " [%6ld,%6ld]\n", pInter->min, pInter->max); + fflush (stdout); + } +} + + +/* ------------------------------------------------------------------ + * Function : "addinter()". + */ + +extern struct lInter_s *addinter (apInter, aMin, aMax) + struct lInter_s *apInter; + long aMin; + long aMax; +{ + struct eInter_s *currInter; + struct eInter_s *newInter; + struct eInter_s mergeInter; + struct eInter_s **ppInter; + + + /* Case of the first interval. */ + if (apInter == NULL) apInter = allocinter (); + + + /* Update the interval list bounds. */ + apInter->max = m_Max(apInter->max, aMax); + apInter->min = m_Min(apInter->min, aMin); + + + mergeInter.min = aMin; + mergeInter.max = aMax; + newInter = NULL; + ppInter = &(apInter->l); + + + for (; *ppInter != NULL;) { + switch (cmpeinter (&mergeInter, *ppInter)) { + case C_INTER_LOWER: break; + case C_INTER_OUT: break; + + case C_INTER_CROSS_MIN: + (*ppInter)->max = mergeInter.max; + newInter = *ppInter; + break; + + case C_INTER_IN: + if (!newInter) { + (*ppInter)->min = mergeInter.min; + (*ppInter)->max = mergeInter.max; + newInter = *ppInter; + } else { + currInter = *ppInter; + *ppInter = (*ppInter)->next; + freeeinter (currInter); + apInter->len -= 1; + continue; + } + break; + + case C_INTER_CROSS_MAX: + if (!newInter) { + (*ppInter)->min = mergeInter.min; + newInter = *ppInter; + } else { + newInter->max = (*ppInter)->max; + mergeInter.max = (*ppInter)->max; + + currInter = *ppInter; + *ppInter = (*ppInter)->next; + freeeinter (currInter); + apInter->len -= 1; + continue; + } + break; + + case C_INTER_GREATER: + if (!newInter) { + newInter = alloceinter (mergeInter.min, mergeInter.max); + newInter->next = *ppInter; + *ppInter = newInter; + apInter->len += 1; + } + break; + } + + ppInter = &((*ppInter)->next); + } + + + /* Tail of first added interval. */ + if (!newInter) { + *ppInter = alloceinter (aMin, aMax); + apInter->len += 1; + } + + + return (apInter); +} + + +/* ------------------------------------------------------------------ + * Function : "freeinter()". + */ + +extern void freeinter (apInter) + struct lInter_s *apInter; +{ + struct eInter_s *pNextInter; + struct eInter_s *pInter; + + + for (pInter = apInter->l; pInter != NULL; ) { + pNextInter = pInter->next; + + freeeinter (pInter); + + pInter = pNextInter; + } + + mbkfree ((void*)apInter); +} diff --git a/alliance/src/sea/src/util_LEFDEF.c b/alliance/src/sea/src/util_LEFDEF.c new file mode 100644 index 00000000..d621d5e3 --- /dev/null +++ b/alliance/src/sea/src/util_LEFDEF.c @@ -0,0 +1,643 @@ +/* + * $Id: util_LEFDEF.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./util_LEFDEF.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "debugoff.h" +# include "util_Defs.h" + + +/* ------------------------------------------------------------------ + * Global variables (declared `extern' in "util_Defs.h"). + */ + + long DEF_UNITS_MICRONS = 100L; + + + static char *getRowToken __FP((char *aS, char *aSepar, char *aRefName)); + + +/* + * /----------------------------------------------------------------\ + * | Functions Definitions | + * \----------------------------------------------------------------/ + */ + + +/* ------------------------------------------------------------------ + * Function : "DEF2MBK_length()". + */ + +extern long DEF2MBK_length(aL) + long aL; +{ + return ((aL * SCALE_X) / DEF_UNITS_MICRONS); +} + + +/* ------------------------------------------------------------------ + * Function : "MBK2DEF_length()". + */ + +extern long MBK2DEF_length(aL) + long aL; +{ + return ((aL * DEF_UNITS_MICRONS) / SCALE_X); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF2MBK_name()". + */ + +extern char *DEF2MBK_name(aS) + char *aS; +{ + int iS; + char *sTmp, *sAlloc, *pDelim; + + + iS = 0; if (aS[0] == '|') iS++; + sTmp = strdup (&aS[iS]); + + /* Translate '|' (hierarchical separator) to SEPAR. */ + for (iS = 0; sTmp[iS] != '\0'; iS++) + if (sTmp[iS] == '|') sTmp[iS] = SEPAR; + + /* Translate vectorisation : "name<2>" --> "name 2". */ + if ((pDelim = strchr (sTmp, '<'))) *pDelim = ' '; + if ((pDelim = strchr (sTmp, '>'))) *pDelim = '\0'; + if ((pDelim = strchr (sTmp, '('))) *pDelim = ' '; + if ((pDelim = strchr (sTmp, ')'))) *pDelim = '\0'; + + sAlloc = namealloc (sTmp); + free (sTmp); + + + return (sAlloc); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF2MBK_row()". + */ + +extern struct phref *DEF2MBK_row(apPhfig, + aRowName, aRowType, + aOrient, + aDoNumber, aByNumber, + aStepX, aStepY, + aX, aY) + struct phfig *apPhfig; + char *aRowName, *aRowType; + long aOrient; + long aDoNumber, aByNumber; + long aStepX, aStepY; + long aX, aY; +{ + static char ref_name[16384]; + + + sprintf (ref_name, + "%s.%s.%s_do_%ld_by_%ld_step_%ld_%ld", + aRowName, + aRowType, + DEF_orient2a(aOrient), + aDoNumber, + aByNumber, + aStepX, + aStepY); + + return (addphref(apPhfig, + "ref_ref", + ref_name, + aX, + aY)); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF2MBK_track()". + */ + +extern struct phref *DEF2MBK_track(apPhfig, + aAxisName, + aStart, + aDoNumber, + aStep, + asLayers, + aX, aY) + struct phfig *apPhfig; + char *aAxisName; + long aStart; + long aDoNumber; + long aStep; + char *asLayers; + long aX, aY; +{ + static char ref_name[16384]; + + + sprintf (ref_name, + "tracks.%s_%ld_do_%ld_step_%ld.%s", + aAxisName, + aStart, + aDoNumber, + aStep, + asLayers); + + return (addphref(apPhfig, + "ref_ref", + ref_name, + aX, + aY)); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF2MBK_blockage()". + */ + +extern struct phref *DEF2MBK_blockage(apPhfig, aX, aY, aWidth, aHeight) + struct phfig *apPhfig; + long aX, aY, aWidth, aHeight; +{ + static char ref_name[16384]; + + + sprintf (ref_name, + "blockage.%ld_%ld", + aWidth, + aHeight); + + return (addphref(apPhfig, + "ref_ref", + ref_name, + aX, + aY)); +} + + +/* ------------------------------------------------------------------ + * Function : "MBK2DEF_name()". + */ + +extern char *MBK2DEF_name(asLEF, asMBK) + char *asLEF, *asMBK; +{ + char sTmp[1024], *pS, *pI; + + + strncpy (sTmp, asMBK, 1023); + + /* Find the signal index separator ' '. */ + pI = (char*)NULL; + for(pS = sTmp; (*pS) != (char)0; pS++) if ((*pS) == ' ') pI = pS; + + + if (pI != (char*)NULL) { + *pI = (char)0; pI += 1; + sprintf (asLEF, "%s(%s)", sTmp, pI); + } else { + sprintf (asLEF, sTmp); + } + + return (asLEF); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF2MBK_transf()". + */ + +extern char DEF2MBK_transf(aO) + double aO; +{ + switch ((long)aO) { + case DEF_N: return (NOSYM); + case DEF_S: return (SYMXY); + case DEF_W: return (ROT_P); + case DEF_E: return (ROT_M); + case DEF_FN: return (SYM_X); + case DEF_FS: return (SYM_Y); + case DEF_FW: return (SY_RM); + case DEF_FE: return (SY_RP); + } + + return (NOSYM); +} + + +/* ------------------------------------------------------------------ + * Function : "MBK2DEF_direction()". + */ + +extern char MBK2DEF_direction(acDir) + char acDir; +{ + switch(acDir) { + case IN: return (C_DIRECTION_INPUT); + case OUT: return (C_DIRECTION_OUTPUT); + case INOUT: return (C_DIRECTION_INOUT); + case TRANSCV: + case TRISTATE: return (C_DIRECTION_TRISTATE); + } + + return (C_DIRECTION_NONE); +} + + +/* ------------------------------------------------------------------ + * Function : "MBK2DEF_locondir()". + */ + +extern char MBK2DEF_locondir (apLocon) + locon_list *apLocon; +{ + char dir; + + + dir = MBK2DEF_direction (apLocon->DIRECTION); + + if (dir == C_DIRECTION_NONE) { + dir = C_DIRECTION_INPUT; + wprinth (NULL); + wprintf ("Unknown direction for terminal \"%s\" (forced \"INPUT\").\n", + apLocon->NAME); + } + + return (dir); +} + + +/* ------------------------------------------------------------------ + * Function : "BEH2DEF_direction()". + */ + +extern char BEH2DEF_direction(acDir) + char acDir; +{ + switch (acDir) { + case 'I': return (C_DIRECTION_INPUT); + case 'O': return (C_DIRECTION_OUTPUT); + case 'B': return (C_DIRECTION_INOUT); + case 'Z': + case 'T': return (C_DIRECTION_TRISTATE); + } + + return (C_DIRECTION_NONE); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF2MBK_direction()". + */ + +extern char DEF2MBK_direction(aDEFdir) + double aDEFdir; +{ + switch ((long)aDEFdir) { + case DEF_INPUT: return (IN); + case DEF_OUTPUT: return (OUT); + case DEF_INOUT: return (INOUT); + case DEF_FEEDTHRU: return (INOUT); + } + + return (UNKNOWN); +} + + +/* ------------------------------------------------------------------ + * Function : "MBK2DEF_transf()". + */ + +extern char MBK2DEF_transf(aO) + char aO; +{ + switch (aO) { + case NOSYM: return (DEF_N); + case SYMXY: return (DEF_S); + case ROT_P: return (DEF_W); + case ROT_M: return (DEF_E); + case SYM_X: return (DEF_FN); + case SYM_Y: return (DEF_FS); + case SY_RP: return (DEF_FW); + case SY_RM: return (DEF_FE); + } + + return (DEF_N); +} + + +/* ------------------------------------------------------------------ + * Function : "getRowToken()". + */ + +static char *getRowToken(aS, aSepar, aRefName) + char *aS, *aSepar, *aRefName; +{ + char *token; + + if ((token = strtok (aS, aSepar)) == NULL) { + errMBK ("defsavelophfig"); + eprintf ("Malformed row reference name :\n \"%s\"\n", + aRefName); + EXIT (1); + } + + return (token); +} + + + +/* ------------------------------------------------------------------ + * Function : "MBK2DEF_row()". + */ + +extern void MBK2DEF_row(apPhref, + appRowName, appRowType, + apOrient, + apDoNumber, apByNumber, + apStepX, apStepY, + apX, apY) + struct phref *apPhref; + char **appRowName, **appRowType; + long *apOrient; + long *apDoNumber, *apByNumber; + long *apStepX, *apStepY; + long *apX, *apY; +{ + static char ref_name[16384]; + char *token; + + + strcpy (ref_name, apPhref->NAME); + + token = getRowToken (ref_name, ".", apPhref->NAME); + *appRowName = (char*)mbkalloc (sizeof (char) * strlen (token)); + strcpy (*appRowName, token); + strtoup (*appRowName); + + token = getRowToken (NULL, ".", apPhref->NAME); + *appRowType = (char*)mbkalloc (sizeof (char) * strlen (token)); + strcpy (*appRowType, token); + + token = strtoup (getRowToken (NULL, "_", apPhref->NAME)); + *apOrient = DEF_a2orient (token); + + token = strtoup (getRowToken (NULL, "_", apPhref->NAME)); + token = strtoup (getRowToken (NULL, "_", apPhref->NAME)); + *apDoNumber = atol (token); + + token = strtoup (getRowToken (NULL, "_", apPhref->NAME)); + token = strtoup (getRowToken (NULL, "_", apPhref->NAME)); + *apByNumber = atol (token); + + token = strtoup (getRowToken (NULL, "_", apPhref->NAME)); + token = strtoup (getRowToken (NULL, "_", apPhref->NAME)); + *apStepX = atol (token); + + token = strtoup (getRowToken (NULL, "_", apPhref->NAME)); + *apStepY = atol (token); + + *apX = apPhref->XREF; + *apY = apPhref->YREF; +} + + +/* ------------------------------------------------------------------ + * Function : "MBK2DEF_track()". + */ + +extern void MBK2DEF_track(apPhref, + apAxisName, + apStart, + apDoNumber, + apStep, + apsLayers, + apX, apY) + struct phref *apPhref; + char *apAxisName; + long *apStart; + long *apDoNumber; + long *apStep; + char **apsLayers; + long *apX, *apY; +{ + static char ref_name[16384]; + char *token; + + + strcpy (ref_name, apPhref->NAME); + + token = getRowToken (ref_name, ".", apPhref->NAME); + token = getRowToken (NULL, "_", apPhref->NAME); + *apAxisName = (char)toupper ((int)*token); + + token = getRowToken (NULL, "_", apPhref->NAME); + *apStart = atol (token); + + token = getRowToken (NULL, "_", apPhref->NAME); + token = getRowToken (NULL, "_", apPhref->NAME); + *apDoNumber = atol (token); + + token = getRowToken (NULL, "_", apPhref->NAME); + token = getRowToken (NULL, ".", apPhref->NAME); + *apStep = atol (token); + + token = getRowToken (NULL, ";", apPhref->NAME); + *apsLayers = (char*)mbkalloc (sizeof (char) * strlen (token)); + strcpy (*apsLayers, token); + strtoup (*apsLayers); + + for (token = *apsLayers; *token != '\0'; token++) + if (*token == '.') *token = ' '; + + *apX = apPhref->XREF; + *apY = apPhref->YREF; +} + + +/* ------------------------------------------------------------------ + * Function : "MBK2DEF_blockage()". + */ + +extern void MBK2DEF_blockage(apPhref, apXB1, apYB1, apWidth, apHeight) + struct phref *apPhref; + long *apXB1, *apYB1, *apWidth, *apHeight; +{ + static char ref_name[16384]; + char *token; + + + strcpy (ref_name, apPhref->NAME); + + token = getRowToken (ref_name, ".", apPhref->NAME); + token = getRowToken (NULL, "_", apPhref->NAME); + *apWidth = atol (token); + + token = getRowToken (NULL, "_", apPhref->NAME); + *apHeight = atol (token); + + *apXB1 = apPhref->XREF; + *apYB1 = apPhref->YREF; +} + + +/* ------------------------------------------------------------------ + * Function : "DEF_orient2a()". + */ + +extern char *DEF_orient2a(aT) + long aT; +{ + static char *tTransf[] = { "N", "S", "W", "E", "FN", "FS", "FW", "FE" }; + + + switch (aT) { + case DEF_N: return (tTransf[0]); + case DEF_S: return (tTransf[1]); + case DEF_W: return (tTransf[2]); + case DEF_E: return (tTransf[3]); + case DEF_FN: return (tTransf[4]); + case DEF_FS: return (tTransf[5]); + case DEF_FW: return (tTransf[6]); + case DEF_FE: return (tTransf[7]); + } + + return (tTransf[0]); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF_a2orient()". + */ + +extern long DEF_a2orient(aT) + char *aT; +{ + if (!strcmp (aT, "N")) return (DEF_N); + if (!strcmp (aT, "S")) return (DEF_S); + if (!strcmp (aT, "W")) return (DEF_W); + if (!strcmp (aT, "E")) return (DEF_E); + if (!strcmp (aT, "FN")) return (DEF_FN); + if (!strcmp (aT, "FS")) return (DEF_FS); + if (!strcmp (aT, "FW")) return (DEF_FW); + if (!strcmp (aT, "FE")) return (DEF_FE); + + return (DEF_N); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF_side2a()". + */ + +extern char *DEF_side2a(aSide) + char aSide; +{ + static char *tTransf[] = { "N", "S", "W", "E" }; + + + switch (aSide) { + case SOUTH: return (tTransf[0]); + case NORTH: return (tTransf[1]); + case EAST: return (tTransf[2]); + case WEST: return (tTransf[3]); + } + + return (tTransf[0]); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF_layer2a()". + */ + +extern char *DEF_layer2a(aLayer) + char aLayer; +{ + char *layerName; + + + __DBG (fprintf (stderr, "layer id %d\n", (int)aLayer); ) + switch (aLayer) { + case ALU1: layerName = "L_ALU1"; break; + case ALU2: layerName = "L_ALU2"; break; + case ALU3: layerName = "L_ALU3"; break; + case ALU4: layerName = "L_ALU4"; break; + case ALU5: layerName = "L_ALU5"; break; + case ALU6: layerName = "L_ALU6"; break; + case ALU7: layerName = "L_ALU7"; break; + case ALU8: layerName = "L_ALU8"; break; + case CALU1: layerName = "L_ALU1"; break; + case CALU2: layerName = "L_ALU2"; break; + case CALU3: layerName = "L_ALU3"; break; + case CALU4: layerName = "L_ALU4"; break; + case CALU5: layerName = "L_ALU5"; break; + case CALU6: layerName = "L_ALU6"; break; + case CALU7: layerName = "L_ALU7"; break; + case CALU8: layerName = "L_ALU8"; break; + case CONT_VIA: layerName = "L_VIA1"; break; + case CONT_VIA2: layerName = "L_VIA2"; break; + case CONT_VIA3: layerName = "L_VIA3"; break; + case CONT_VIA4: layerName = "L_VIA4"; break; + case CONT_VIA5: layerName = "L_VIA5"; break; + case CONT_VIA6: layerName = "L_VIA6"; break; + case CONT_VIA7: layerName = "L_VIA7"; break; + default: layerName = "L_MBK_ERROR"; break; + } + + return (layerName); +} + + +/* ------------------------------------------------------------------ + * Function : "DEF_via2a()". + */ + +extern char *DEF_via2a(aType, aDX, aDY, aViaName) + char aType; + long aDX, aDY; + char *aViaName; +{ + long flagDefault, length; + + + switch (aType) { + case CONT_VIA: strcpy (aViaName, "CONT_VIA"); break; + case CONT_VIA2: strcpy (aViaName, "CONT_VIA2"); break; + case CONT_VIA3: strcpy (aViaName, "CONT_VIA3"); break; + case CONT_VIA4: strcpy (aViaName, "CONT_VIA4"); break; + case CONT_VIA5: strcpy (aViaName, "CONT_VIA5"); break; + case CONT_VIA6: strcpy (aViaName, "CONT_VIA6"); break; + case CONT_VIA7: strcpy (aViaName, "CONT_VIA7"); break; + default: strcpy (aViaName, "MBK_ERROR"); break; + } + length = strlen (aViaName); + + flagDefault = (aDX <= MBKSCALE(2)) + && (aDY <= MBKSCALE(2)); + + if (!flagDefault) { + sprintf (aViaName + length, "_%ld_%ld", + MBK2DEF_length (aDX), + MBK2DEF_length (aDY)); + } + + return (aViaName); +} diff --git a/alliance/src/sea/src/util_MBK.c b/alliance/src/sea/src/util_MBK.c new file mode 100644 index 00000000..7c1d5d1b --- /dev/null +++ b/alliance/src/sea/src/util_MBK.c @@ -0,0 +1,2375 @@ + +/* + * $Id: util_MBK.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./util_MBK.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" +# include "debugoff.h" + + +# define C_POWER_VDD (0) +# define C_POWER_VSS (1) +# define C_POWER_UNKNOWN (1024) + +# define TLOSEG_SIZE (512) + +# define SIZE_SNAME (1024) + + +/* ------------------------------------------------------------------ + * Internal types. + */ + + typedef struct sigalias_s { + char *name; /* The main signal name (getsigname()). */ + long flags; /* The subnet field. */ + } sigalias_t; + + + +/* ------------------------------------------------------------------ + * Global variables (declared `extern' in "util_Defs.h"). + */ + + long MBK_sigIndex = 0L; + + +/* ------------------------------------------------------------------ + * Local variables. + */ + + static authtable *LV_htSigAlias = NULL; + static struct sigalias_s *LV_tSigAlias = NULL; + + +/* ------------------------------------------------------------------ + * Local functions declarations. + */ + + static void buildtsigalias __FP((struct losig *apLosig)); + static void freetsigalias __FP((void)); + + static char *getlosegname __FP((struct eLoseg_s *apLoseg)); + + +/* + * /----------------------------------------------------------------\ + * | Functions Definitions | + * \----------------------------------------------------------------/ + */ + +/* ------------------------------------------------------------------ + * Function : "isobs()". + */ + +extern long isobs(apSeg) + struct phseg *apSeg; +{ + switch (apSeg->LAYER) { + case TALU1: + case TALU2: + case TALU3: + case TALU4: + case TALU5: + case TALU6: + case TALU7: + case TALU8: + case TALU9: + return (TRUE); + } + + return (FALSE); +} + + +/* ------------------------------------------------------------------ + * Function : "getsigaliasnumber()". + */ + +extern long getsigaliasnumber(apLosig) + struct losig *apLosig; +{ + struct chain *pChain; + long aliasNumber; + + + aliasNumber = 0; + + for (pChain = apLosig->NAMECHAIN; pChain != NULL; pChain = pChain->NEXT) { + aliasNumber++; + } + + return (aliasNumber - 1); +} + + +/* ------------------------------------------------------------------ + * Function : "signamecmp()". + */ + +extern long signamecmp(aLoname, aPhname) + char *aLoname, *aPhname; +{ + char *pS, *pVector; + char losigName[SIZE_SNAME]; + + + if (aLoname == aPhname) return (TRUE); + + /* Try to guess if the losig name was a vector name. */ + strcpy (losigName, aLoname); + + pVector = NULL; + for (pS = losigName; pS != '\0'; pS++) + if (*pS == '_') pVector = pS; + + if (!pVector) return (FALSE); + + for (pS = pVector + 1; pS != '\0'; pS++) + if (!isdigit ((int)*pS)) return (FALSE); + + *pVector = ' '; + + if (!strcmp (losigName, aPhname)) return (TRUE); + + return (FALSE); +} + + +/* ------------------------------------------------------------------ + * Function : "makesegnamelist()". + */ + +extern char **makesegnamelist(aName) + char *aName; +{ + static char *tSegAlias[1024]; + long mSegAlias; + char *pS, *pVector; + char losegName[SIZE_SNAME]; +# if 0 + char pathName[SIZE_SNAME]; +# endif + long iEnd; + + + mSegAlias = 0; + strcpy (losegName, aName); + iEnd = strlen (losegName) - 1; + + + /* Add the signal name "as is". */ + tSegAlias[mSegAlias++] = namealloc (losegName); + + /* Try to find if it is a vector. */ + pVector = NULL; + for (pS = losegName + iEnd; pS != losegName; pS--) { + if (*pS == ' ') { + *pS = '_'; + tSegAlias[mSegAlias++] = namealloc (losegName); + } + } + + +# if 0 + /* This code is no longer needed, for we. */ + /* Loop on the path name, using SEPAR. */ + for (; iEnd > 0; iEnd--) { + if (losegName[iEnd] == SEPAR) { + strncpy (pathName, losegName, iEnd); + pathName[iEnd] = '\0'; + + /* Add the path name "as is". */ + tSegAlias[mSegAlias++] = pathName; + + /* Try to find if it is a vector. */ + pVector = NULL; + for (pS = pathName + iEnd; pS != pathName; pS--) { + if (*pS == ' ') { + *pS = '_'; + tSegAlias[mSegAlias++] = pathName; + } + } + } + } /* End of "iEnd" loop. */ +# endif + + + tSegAlias[mSegAlias++] = NULL; + + return (tSegAlias); +} + + +/* ------------------------------------------------------------------ + * Function : "printMBKEnv()". + */ + +extern void printMBKEnv() +{ + int i; + + mprintf2 (" o MBK environment :\n\n" ); + mprintf2 (" MBK_IN_LO := %s\n", IN_LO ); + mprintf2 (" MBK_OUT_LO := %s\n", OUT_LO ); + mprintf2 (" MBK_IN_PH := %s\n", IN_PH ); + mprintf2 (" MBK_OUT_PH := %s\n", OUT_PH ); + mprintf2 (" MBK_WORK_LIB := %s\n", WORK_LIB); + + for(i = 0; CATA_LIB[i] != (char *)NULL; i++) { + if (i == 0) mprintf2 (" MBK_CATA_LIB := "); + else mprintf2 (" "); + mprintf2 ("%s\n", CATA_LIB[i]); + } + + mprintf2 (" MBK_CATAL_NAME := %s\n", CATAL); + mprintf2 (" MBK_VDD := %s\n", VDD ); + mprintf2 (" MBK_VSS := %s\n", VSS ); + mprintf2 (" MBK_SEPAR := %c\n", SEPAR); + mprintf2 ("\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "getAltVIALayer()". + */ + +extern char getAltVIALayer(aVIA, aLayer) + char aVIA, aLayer; +{ + char topLayer, bottomLayer, topCLayer, bottomCLayer, dualLayer; + + + topLayer = ALU1; + bottomLayer = ALU2; + topCLayer = CALU1; + bottomCLayer = CALU2; + + switch (aVIA) { + case CONT_POLY: + topLayer = ALU1; bottomLayer = POLY; + topCLayer = CALU1; bottomCLayer = POLY; + break; + case CONT_VIA: + topLayer = ALU2; bottomLayer = ALU1; + topCLayer = CALU2; bottomCLayer = CALU1; + break; + case CONT_VIA2: + topLayer = ALU3; bottomLayer = ALU2; + topCLayer = CALU3; bottomCLayer = CALU2; + break; + case CONT_VIA3: + topLayer = ALU4; bottomLayer = ALU3; + topCLayer = CALU4; bottomCLayer = CALU3; + break; + case CONT_VIA4: + topLayer = ALU5; bottomLayer = ALU4; + topCLayer = CALU5; bottomCLayer = CALU4; + break; + case CONT_VIA5: + topLayer = ALU6; bottomLayer = ALU5; + topCLayer = CALU6; bottomCLayer = CALU5; + break; + case CONT_VIA6: + topLayer = ALU7; bottomLayer = ALU6; + topCLayer = CALU7; bottomCLayer = CALU6; + break; + case CONT_VIA7: + topLayer = ALU8; bottomLayer = ALU7; + topCLayer = CALU8; bottomCLayer = CALU7; + break; + case CONT_VIA8: + topLayer = ALU9; bottomLayer = ALU8; + topCLayer = CALU9; bottomCLayer = CALU8; + break; + case CONT_TURN1: + topLayer = ALU1; bottomLayer = ALU1; + topCLayer = CALU1; bottomCLayer = CALU1; + break; + case CONT_TURN2: + topLayer = ALU2; bottomLayer = ALU2; + topCLayer = CALU2; bottomCLayer = CALU2; + break; + case CONT_TURN3: + topLayer = ALU3; bottomLayer = ALU3; + topCLayer = CALU3; bottomCLayer = CALU3; + break; + case CONT_TURN4: + topLayer = ALU4; bottomLayer = ALU4; + topCLayer = CALU4; bottomCLayer = CALU4; + break; + case CONT_TURN5: + topLayer = ALU5; bottomLayer = ALU5; + topCLayer = CALU5; bottomCLayer = CALU5; + break; + case CONT_TURN6: + topLayer = ALU6; bottomLayer = ALU6; + topCLayer = CALU6; bottomCLayer = CALU6; + break; + case CONT_TURN7: + topLayer = ALU7; bottomLayer = ALU7; + topCLayer = CALU7; bottomCLayer = CALU7; + break; + case CONT_TURN8: + topLayer = ALU8; bottomLayer = ALU8; + topCLayer = CALU8; bottomCLayer = CALU8; + break; + case CONT_TURN9: + topLayer = ALU9; bottomLayer = ALU9; + topCLayer = CALU9; bottomCLayer = CALU9; + break; + default: + errMBK ("getAltVIALayer"); + eprintf ("Unknown VIA id %d.\n", (int)aVIA); + EXIT (1); + } + + + /* ALU connectivity. */ + dualLayer = (aLayer == topLayer) ? bottomLayer : + ((aLayer == bottomLayer) ? topLayer : (LAST_LAYER + 1)); + + /* CALU connectivity. */ + if (dualLayer == LAST_LAYER + 1) { + __DBG( + fprintf (stderr, "This is a CALU %d %d | ", (int)aVIA, (int)aLayer); + fprintf (stderr, "topC = %d, bottomC = %d, ", (int)topCLayer, + (int)bottomCLayer); + ) + dualLayer = (aLayer == topCLayer) ? bottomCLayer : + ((aLayer == bottomCLayer) ? topCLayer : (LAST_LAYER + 1)); + __DBG( fprintf (stderr, "Layer is now %d\n", (int)dualLayer); ) + } + + if (dualLayer == LAST_LAYER + 1) { + errMBK ("getAltVIALayer"); + eprintf ("VIA id %d is not contiguous with layer id %d\n", + (int)aVIA, (int)aLayer); + EXIT (1); + } + + return (dualLayer); +} + + +/* ------------------------------------------------------------------ + * Function : "getTopVIALayer()". + */ + +extern char getTopVIALayer(aVIA) + char aVIA; +{ + char topLayer; + + + topLayer = ALU1; + + switch (aVIA) { + case CONT_BODY_N: topLayer = ALU1; break; + case CONT_BODY_P: topLayer = ALU1; break; + case CONT_DIF_N: topLayer = ALU1; break; + case CONT_DIF_P: topLayer = ALU1; break; + case CONT_POLY: topLayer = ALU1; break; + case CONT_POLY2: topLayer = ALU1; break; + case CONT_VIA: topLayer = ALU2; break; + case CONT_VIA2: topLayer = ALU3; break; + case CONT_VIA3: topLayer = ALU4; break; + case CONT_VIA4: topLayer = ALU5; break; + case CONT_VIA5: topLayer = ALU6; break; + case CONT_VIA6: topLayer = ALU7; break; + case CONT_VIA7: topLayer = ALU8; break; + case CONT_VIA8: topLayer = ALU9; break; + case CONT_TURN1: topLayer = ALU1; break; + case CONT_TURN2: topLayer = ALU2; break; + case CONT_TURN3: topLayer = ALU3; break; + case CONT_TURN4: topLayer = ALU4; break; + case CONT_TURN5: topLayer = ALU5; break; + case CONT_TURN6: topLayer = ALU6; break; + case CONT_TURN7: topLayer = ALU7; break; + case CONT_TURN8: topLayer = ALU8; break; + case CONT_TURN9: topLayer = ALU9; break; + default: + errMBK ("getTopVIALayer"); + eprintf ("Unknown VIA id %d.\n", (int)aVIA); + EXIT (1); + } + + + return (topLayer); +} + + +/* ------------------------------------------------------------------ + * Function : "getBottomVIALayer()". + */ + +extern char getBottomVIALayer(aVIA) + char aVIA; +{ + char bottomLayer; + + + bottomLayer = ALU1; + + switch (aVIA) { + case CONT_BODY_N: bottomLayer = NWELL; break; + case CONT_BODY_P: bottomLayer = PWELL; break; + case CONT_DIF_N: bottomLayer = NDIF; break; + case CONT_DIF_P: bottomLayer = PDIF; break; + case CONT_POLY: bottomLayer = POLY; break; + case CONT_POLY2: bottomLayer = POLY2; break; + case CONT_VIA: bottomLayer = ALU1; break; + case CONT_VIA2: bottomLayer = ALU2; break; + case CONT_VIA3: bottomLayer = ALU3; break; + case CONT_VIA4: bottomLayer = ALU4; break; + case CONT_VIA5: bottomLayer = ALU5; break; + case CONT_VIA6: bottomLayer = ALU6; break; + case CONT_VIA7: bottomLayer = ALU7; break; + case CONT_VIA8: bottomLayer = ALU8; break; + case CONT_TURN1: bottomLayer = ALU1; break; + case CONT_TURN2: bottomLayer = ALU2; break; + case CONT_TURN3: bottomLayer = ALU3; break; + case CONT_TURN4: bottomLayer = ALU4; break; + case CONT_TURN5: bottomLayer = ALU5; break; + case CONT_TURN6: bottomLayer = ALU6; break; + case CONT_TURN7: bottomLayer = ALU7; break; + case CONT_TURN8: bottomLayer = ALU8; break; + case CONT_TURN9: bottomLayer = ALU9; break; + default: + errMBK ("getBottomVIALayer"); + eprintf ("Unknown VIA id %d.\n", (int)aVIA); + EXIT (1); + } + + + return (bottomLayer); +} + + +/* ------------------------------------------------------------------ + * Function : "isVIALayer()". + */ + +extern long isVIALayer(aVIA, aLayer) + char aVIA; + char aLayer; +{ + switch (aVIA) { + case CONT_BODY_N: + if (aLayer == NWELL) return (TRUE); + case CONT_BODY_P: + if (aLayer == PWELL) return (TRUE); + if (aLayer == ALU1) return (TRUE); + if (aLayer == CALU1) return (TRUE); + break; + case CONT_DIF_N: + if (aLayer == NDIF) return (TRUE); + case CONT_DIF_P: + if (aLayer == PDIF) return (TRUE); + if (aLayer == ALU1) return (TRUE); + if (aLayer == CALU1) return (TRUE); + break; + case CONT_POLY: + if (aLayer == POLY) return (TRUE); + if (aLayer == ALU1) return (TRUE); + if (aLayer == CALU1) return (TRUE); + break; + case CONT_POLY2: + if (aLayer == POLY2) return (TRUE); + if (aLayer == ALU1) return (TRUE); + if (aLayer == CALU1) return (TRUE); + break; + case CONT_VIA8: + if (aLayer == ALU9) return (TRUE); + if (aLayer == CALU9) return (TRUE); + case CONT_VIA7: + if (aLayer == ALU8) return (TRUE); + if (aLayer == CALU8) return (TRUE); + case CONT_VIA6: + if (aLayer == ALU7) return (TRUE); + if (aLayer == CALU7) return (TRUE); + case CONT_VIA5: + if (aLayer == ALU6) return (TRUE); + if (aLayer == CALU6) return (TRUE); + case CONT_VIA4: + if (aLayer == ALU5) return (TRUE); + if (aLayer == CALU5) return (TRUE); + case CONT_VIA3: + if (aLayer == ALU4) return (TRUE); + if (aLayer == CALU4) return (TRUE); + case CONT_VIA2: + if (aLayer == ALU3) return (TRUE); + if (aLayer == CALU3) return (TRUE); + case CONT_VIA: + if (aLayer == ALU2) return (TRUE); + if (aLayer == CALU2) return (TRUE); + if (aLayer == ALU1) return (TRUE); + if (aLayer == CALU1) return (TRUE); + break; + case CONT_TURN9: + if (aLayer == ALU9) return (TRUE); + if (aLayer == CALU9) return (TRUE); + break; + case CONT_TURN8: + if (aLayer == ALU8) return (TRUE); + if (aLayer == CALU8) return (TRUE); + break; + case CONT_TURN7: + if (aLayer == ALU7) return (TRUE); + if (aLayer == CALU7) return (TRUE); + break; + case CONT_TURN6: + if (aLayer == ALU6) return (TRUE); + if (aLayer == CALU6) return (TRUE); + break; + case CONT_TURN5: + if (aLayer == ALU5) return (TRUE); + if (aLayer == CALU5) return (TRUE); + break; + case CONT_TURN4: + if (aLayer == ALU4) return (TRUE); + if (aLayer == CALU4) return (TRUE); + break; + case CONT_TURN3: + if (aLayer == ALU3) return (TRUE); + if (aLayer == CALU3) return (TRUE); + break; + case CONT_TURN2: + if (aLayer == ALU2) return (TRUE); + if (aLayer == CALU2) return (TRUE); + break; + case CONT_TURN1: + if (aLayer == ALU1) return (TRUE); + if (aLayer == CALU1) return (TRUE); + break; + default: + errMBK ("isVIALayer"); + eprintf ("Unknown VIA id %d.\n", (int)aVIA); + EXIT (1); + } + + return (FALSE); +} + + +/* ------------------------------------------------------------------ + * Function : "getUpVIALayer()". + */ + +extern long getUpVIALayer(aVIA, aLayer) + char aVIA; + char aLayer; +{ + char upLayer; + + + if (!isVIALayer (aVIA, aLayer)) { + errMBK ("getUpVIALayer"); + eprintf ("Layer id %d do not belong to VIA id %d.\n", + (int)aLayer, (int)aVIA); + EXIT (1); + } + + upLayer = getUpLayer (aLayer); + if (!isVIALayer (aVIA, upLayer)) upLayer = aLayer; + + return (upLayer); +} + + +/* ------------------------------------------------------------------ + * Function : "getTurnVIA()". + */ + +extern char getTurnVIA(aLayer) + char aLayer; +{ + char turnVIA; + + + turnVIA = CONT_TURN1; + + switch (aLayer) { + case ALU1: + case CALU1: turnVIA = CONT_TURN1; break; + case ALU2: + case CALU2: turnVIA = CONT_TURN3; break; + case ALU3: + case CALU3: turnVIA = CONT_TURN4; break; + case ALU4: + case CALU4: turnVIA = CONT_TURN5; break; + case ALU5: + case CALU5: turnVIA = CONT_TURN6; break; + case ALU6: + case CALU6: turnVIA = CONT_TURN7; break; + case ALU7: + case CALU7: turnVIA = CONT_TURN8; break; + case ALU8: + case CALU8: turnVIA = CONT_TURN9; break; + case ALU9: + case CALU9: turnVIA = CONT_TURN9; break; + default: + errMBK ("getTurnVIA"); + eprintf ("No turn VIA for layer id %d.\n", (int)aLayer); + EXIT (1); + } + + return (turnVIA); +} + + +/* ------------------------------------------------------------------ + * Function : "getUpLayer()". + */ + +extern char getUpLayer(aLayer) + char aLayer; +{ + char upLayer; + + + upLayer = ALU1; + + switch (aLayer) { + case NWELL: upLayer = ALU1; break; + case PWELL: upLayer = ALU1; break; + case NTIE: upLayer = ALU1; break; + case PTIE: upLayer = ALU1; break; + case NDIF: upLayer = ALU1; break; + case PDIF: upLayer = ALU1; break; + case NTRANS: upLayer = ALU1; break; + case PTRANS: upLayer = ALU1; break; + case POLY: upLayer = ALU1; break; + case ALU1: upLayer = ALU2; break; + case CALU1: upLayer = ALU2; break; + case TALU1: upLayer = ALU2; break; + case ALU2: upLayer = ALU3; break; + case CALU2: upLayer = ALU3; break; + case TALU2: upLayer = ALU3; break; + case ALU3: upLayer = ALU4; break; + case CALU3: upLayer = ALU4; break; + case TALU3: upLayer = ALU4; break; + case ALU4: upLayer = ALU5; break; + case CALU4: upLayer = ALU5; break; + case TALU4: upLayer = ALU5; break; + case ALU5: upLayer = ALU6; break; + case CALU5: upLayer = ALU6; break; + case TALU5: upLayer = ALU6; break; + case ALU6: upLayer = ALU7; break; + case CALU6: upLayer = ALU7; break; + case TALU6: upLayer = ALU7; break; + case ALU7: upLayer = ALU8; break; + case CALU7: upLayer = ALU8; break; + case TALU7: upLayer = ALU8; break; + case ALU8: upLayer = ALU9; break; + case CALU8: upLayer = ALU9; break; + case TALU8: upLayer = ALU9; break; + case ALU9: upLayer = ALU9; break; + case CALU9: upLayer = ALU9; break; + case TALU9: upLayer = ALU9; break; + default: + errMBK ("getUpLayer"); + eprintf ("Unknown Layer id %d.\n", (int)aLayer); + EXIT (1); + } + + return (upLayer); +} + + +/* ------------------------------------------------------------------ + * Function : "cmpALU()". + */ + +extern long cmpALU(aLayer1, aLayer2) + char aLayer1, aLayer2; +{ + switch(aLayer1) { + case ALU1: + switch(aLayer2) { + case ALU1: return(F_EQUAL_M); + case CALU1: return(F_EQUAL_C); + case TALU1: return(F_EQUAL_T); + } + break; + + case ALU2: + switch(aLayer2) { + case ALU2: return(F_EQUAL_M); + case CALU2: return(F_EQUAL_C); + case TALU2: return(F_EQUAL_T); + } + break; + + case ALU3: + switch(aLayer2) { + case ALU3: return(F_EQUAL_M); + case CALU3: return(F_EQUAL_C); + case TALU3: return(F_EQUAL_T); + } + break; + + case ALU4: + switch(aLayer2) { + case ALU4: return(F_EQUAL_M); + case CALU4: return(F_EQUAL_C); + case TALU4: return(F_EQUAL_T); + } + break; + + case ALU5: + switch(aLayer2) { + case ALU5: return(F_EQUAL_M); + case CALU5: return(F_EQUAL_C); + case TALU5: return(F_EQUAL_T); + } + break; + + case ALU6: + switch(aLayer2) { + case ALU6: return(F_EQUAL_M); + case CALU6: return(F_EQUAL_C); + case TALU6: return(F_EQUAL_T); + } + break; + } + + return(FALSE); +} + + +/* ------------------------------------------------------------------ + * Function : "getALU()". + */ + +extern char getALU(aLayer) + char aLayer; +{ + char ALU; + + + ALU = CALU1; + + switch (aLayer) { + case CALU1: + case ALU1: ALU = ALU1; break; + case CALU2: + case ALU2: ALU = ALU2; break; + case CALU3: + case ALU3: ALU = ALU3; break; + case CALU4: + case ALU4: ALU = ALU4; break; + case CALU5: + case ALU5: ALU = ALU5; break; + case CALU6: + case ALU6: ALU = ALU6; break; + case CALU7: + case ALU7: ALU = ALU7; break; + case CALU8: + case ALU8: ALU = ALU8; break; + case CALU9: + case ALU9: ALU = ALU9; break; + default: + errMBK ("getALU"); + eprintf ("No ALU for layer id %d.\n", (int)aLayer); + EXIT (1); + } + + + return (ALU); +} + + +/* ------------------------------------------------------------------ + * Function : "getCALU()". + */ + +extern char getCALU(aLayer) + char aLayer; +{ + char CALU; + + + CALU = CALU1; + + switch (aLayer) { + case CALU1: + case ALU1: CALU = CALU1; break; + case CALU2: + case ALU2: CALU = CALU2; break; + case CALU3: + case ALU3: CALU = CALU3; break; + case CALU4: + case ALU4: CALU = CALU4; break; + case CALU5: + case ALU5: CALU = CALU5; break; + case CALU6: + case ALU6: CALU = CALU6; break; + case CALU7: + case ALU7: CALU = CALU7; break; + case CALU8: + case ALU8: CALU = CALU8; break; + case CALU9: + case ALU9: CALU = CALU9; break; + default: + errMBK ("getCALU"); + eprintf ("No CALU for layer id %d.\n", (int)aLayer); + EXIT (1); + } + + + return (CALU); +} + + +/* ------------------------------------------------------------------ + * Function : "isCALU()". + */ + +extern long isCALU(aLayer) + char aLayer; +{ + long flag; + + + flag = FALSE; + switch (aLayer) { + case CALU1: + case CALU2: + case CALU3: + case CALU4: + case CALU5: + case CALU6: + case CALU7: + case CALU8: + case CALU9: flag = TRUE; break; + } + + + return (flag); +} + + +/* ------------------------------------------------------------------ + * Function : "getTALU()". + */ + +extern char getTALU(aLayer) + char aLayer; +{ + char TALU; + + + TALU = TALU1; + + switch (aLayer) { + case TALU1: + case CALU1: + case ALU1: TALU = TALU1; break; + case TALU2: + case CALU2: + case ALU2: TALU = TALU2; break; + case TALU3: + case CALU3: + case ALU3: TALU = TALU3; break; + case TALU4: + case CALU4: + case ALU4: TALU = TALU4; break; + case TALU5: + case CALU5: + case ALU5: TALU = TALU5; break; + case TALU6: + case CALU6: + case ALU6: TALU = TALU6; break; + case TALU7: + case CALU7: + case ALU7: TALU = TALU7; break; + case TALU8: + case CALU8: + case ALU8: TALU = TALU8; break; + case TALU9: + case CALU9: + case ALU9: TALU = TALU9; break; + default: + errMBK ("getTALU"); + eprintf ("No TALU for layer id %d.\n", (int)aLayer); + EXIT (1); + } + + + return (TALU); +} + + +/* ------------------------------------------------------------------ + * Function : "getLayerTrackWidth()". + */ + +extern long getLayerTrackWidth(aLayer) + char aLayer; +{ + long trackWidth; + + + trackWidth = MBKSCALE(2); + + switch (aLayer) { + case CALU1: + case TALU1: + case ALU1: trackWidth = MBKSCALE (1); break; + case CALU2: + case TALU2: + case ALU2: + case CALU3: + case TALU3: + case ALU3: + case CALU4: + case TALU4: + case ALU4: + case CALU5: + case TALU5: + case ALU5: + case CALU6: + case TALU6: + case ALU6: + case CALU7: + case TALU7: + case ALU7: + case CALU8: + case TALU8: + case ALU8: + case CALU9: + case TALU9: + case ALU9: trackWidth = MBKSCALE (2); break; + default: + errMBK ("getLayerTrackWidth"); + eprintf ("No minimal track width for layer id %d.\n", (int)aLayer); + EXIT (1); + } + + return (trackWidth); +} + + +/* ------------------------------------------------------------------ + * Function : "xyflatseg()". + */ + +extern void xyflatseg(apFlatSeg, apSeg, + aXINS, aYINS, + aXAB1, aYAB1, + aXAB2, aYAB2, + aTransf) + struct phseg *apFlatSeg, *apSeg; + long aXINS, aYINS, aXAB1, aYAB1, aXAB2, aYAB2; + char aTransf; +{ + long swap; + + + apFlatSeg->NAME = apSeg->NAME; + apFlatSeg->LAYER = apSeg->LAYER; + apFlatSeg->WIDTH = apSeg->WIDTH; + + + xyflat (&apFlatSeg->X1, &apFlatSeg->Y1, + apSeg->X1, apSeg->Y1, + aXINS, aYINS, + aXAB1, aYAB1, + aXAB2, aYAB2, + aTransf); + + xyflat (&apFlatSeg->X2, &apFlatSeg->Y2, + apSeg->X2, apSeg->Y2, + aXINS, aYINS, + aXAB1, aYAB1, + aXAB2, aYAB2, + aTransf); + + + if (apFlatSeg->X1 > apFlatSeg->X2) { + swap = apFlatSeg->X1; + apFlatSeg->X1 = apFlatSeg->X2; + apFlatSeg->X2 = swap; + } + + if (apFlatSeg->Y1 > apFlatSeg->Y2) { + swap = apFlatSeg->Y1; + apFlatSeg->Y1 = apFlatSeg->Y2; + apFlatSeg->Y2 = swap; + } + + if (apFlatSeg->Y1 == apFlatSeg->Y2) { + if (apFlatSeg->X1 < apFlatSeg->X2) apFlatSeg->TYPE = LEFT; + else apFlatSeg->TYPE = RIGHT; + } else { + if (apFlatSeg->Y1 < apFlatSeg->Y2) apFlatSeg->TYPE = UP; + else apFlatSeg->TYPE = DOWN; + } +} + + +/* ------------------------------------------------------------------ + * Function : "isPad()". + */ + +extern long isPad (asCell) + char *asCell; +{ + char *i, *ext; + + ext = NULL; + for(i = asCell; *i != (char)0; i++) + if (*i == '_') ext = i; + + if (ext == NULL) return (FALSE); + if (strcmp (ext, "_sp")) return (FALSE); + + return (TRUE); +} + + +/* ------------------------------------------------------------------ + * Function : "initSigIndex()". + */ + +extern long initSigIndex(apLoSig) + losig_list *apLoSig; +{ + losig_list *pLoSig; + long iMax; + + iMax = 0L; + for(pLoSig = apLoSig; pLoSig != (losig_list*)NULL; pLoSig = pLoSig->NEXT) + if (pLoSig->INDEX > iMax) iMax = pLoSig->INDEX; + + return(MBK_sigIndex = iMax); +} + + +/* ------------------------------------------------------------------ + * Function : "cmpSigName()". + */ + +extern long cmpSigName(apLoSig, asName) + losig_list *apLoSig; + char *asName; +{ + chain_list *pChain; + + + for(pChain = apLoSig->NAMECHAIN; + pChain != (chain_list*)NULL; + pChain = pChain->NEXT) { + if ((char*)(pChain->DATA) == asName) return(TRUE); + } + + return(FALSE); +} + + +/* ------------------------------------------------------------------ + * Function : "addInsLoCon()". + */ + +extern locon_list *addInsLoCon(apIns, asName, apSig, aDir) + loins_list *apIns; + char *asName; + losig_list *apSig; + char aDir; +{ + locon_list *pCon; + char *sName; + + + sName = namealloc(asName); + for(pCon = apIns->LOCON; pCon != (locon_list*)NULL; pCon = pCon->NEXT) { + if (pCon->NAME == sName) { + pCon->SIG = apSig; + return(pCon); + } + } + + pCon = (locon_list*)malloc(sizeof(locon_list)); + pCon->NAME = sName; + pCon->SIG = apSig; + pCon->ROOT = (void*)apIns; + pCon->TYPE = INTERNAL; + pCon->DIRECTION = aDir; + + pCon->NEXT = apIns->LOCON; + apIns->LOCON = pCon; + + return(pCon); +} + + +/* ------------------------------------------------------------------ + * Function : "splitPowerNet()". + */ + +extern void splitPowerNet(apLoFig, asPower) + lofig_list *apLoFig; + char *asPower; +{ + ptype_list *pType; + chain_list *pChain; + locon_list *pLoCon; + loins_list *pLoIns; + losig_list *pSigPower, *pSig; + char *tsSig[2], *sVDD, *sVSS, *sPOW; + long powerType; + + + sVDD = namealloc("vdd"); + sVSS = namealloc("vss"); + + tsSig[C_POWER_VDD] = namealloc("vddi"); + tsSig[C_POWER_VSS] = namealloc("vssi"); + + powerType = C_POWER_UNKNOWN; sPOW = (char*)NULL; + if (!strcmp(asPower, sVDD)) { powerType = C_POWER_VDD; sPOW = sVDD; } + if (!strcmp(asPower, sVSS)) { powerType = C_POWER_VSS; sPOW = sVSS; } + + if (powerType == C_POWER_UNKNOWN) { + eprinth((char*)NULL); + eprintf("\n Only \"vdd\" and \"vss\" can be splitted (%s).\n", asPower); + EXIT (1); + } + + + pChain = addchain((chain_list*)NULL, (void*)tsSig[powerType]); + pSigPower = addlosig(apLoFig, NEWSIGINDEX, pChain, INTERNAL); + + + /* Find the power net to be splitted. */ + for(pSig = apLoFig->LOSIG; pSig != (losig_list*)NULL; pSig = pSig->NEXT) + if (cmpSigName(pSig, sPOW)) break; + + if (pSig == (losig_list*)NULL) { + eprinth((char*)NULL); + eprintf("\n Signal \"%s\" not found for splitting.\n", sPOW); + EXIT (1); + } + + pType = getptype(pSig->USER, (long)LOFIGCHAIN); + if (pType == (ptype_list*)NULL) { + eprinth((char*)NULL); + eprintf("\n Signal \"%s\" have no LOFIGCHAIN.\n", sPOW); + EXIT (1); + } + + + /* Split the power between core cells and pad cells. */ + pChain = (chain_list*)(pType->DATA); + + for(; pChain != (chain_list*)NULL; + pChain = pChain->NEXT) { + pLoCon = (locon_list*)(pChain->DATA); + + if (pLoCon->TYPE == INTERNAL) { + pLoIns = (loins_list*)(pLoCon->ROOT); + + if (isPad(pLoIns->FIGNAME)) pLoCon->SIG = pSigPower; + + if ( (powerType == C_POWER_VDD) + && !strcmp(pLoIns->FIGNAME, "pvddi_sp")) { + addInsLoCon(pLoIns, sPOW, pSig, pLoCon->DIRECTION); + } + + if ( (powerType == C_POWER_VSS) + && !strcmp(pLoIns->FIGNAME, "pvssi_sp")) { + addInsLoCon(pLoIns, sPOW, pSig, pLoCon->DIRECTION); + } + } + } /* End of "pChain" loop. */ +} + + +/* ------------------------------------------------------------------ + * Function : "addPowerNet()". + */ + +extern void addPowerNet(apLoFig, asPower) + lofig_list *apLoFig; + char *asPower; +{ + chain_list *pChain; + losig_list *pSigPower; + char *sPOW; + + + sPOW = namealloc(asPower); + + pChain = addchain((chain_list*)NULL, (void*)sPOW); + pSigPower = addlosig(apLoFig, NEWSIGINDEX, pChain, EXTERNAL); +} + + +/* ------------------------------------------------------------------ + * Function : "xyflatvia()". + */ + +extern void xyflatvia(apFlatVIA, apVIA, + aXINS, aYINS, + aXAB1, aYAB1, + aXAB2, aYAB2, + aTransf) + struct phvia *apFlatVIA, *apVIA; + long aXINS, aYINS, aXAB1, aYAB1, aXAB2, aYAB2; + char aTransf; +{ + apFlatVIA->NAME = apVIA->NAME; + apFlatVIA->TYPE = apVIA->TYPE; + + xyflat (&apFlatVIA->XVIA, &apFlatVIA->YVIA, + apVIA->XVIA, apVIA->YVIA, + aXINS, aYINS, + aXAB1, aYAB1, + aXAB2, aYAB2, + aTransf); + + switch (aTransf) { + case ROT_M: + case ROT_P: + case SY_RM: + case SY_RP: + apFlatVIA->DX = apVIA->DY; + apFlatVIA->DY = apVIA->DX; + break; + case NOSYM: + case SYM_X: + case SYM_Y: + case SYMXY: + default: + apFlatVIA->DX = apVIA->DX; + apFlatVIA->DY = apVIA->DY; + break; + } +} + + +/* ------------------------------------------------------------------ + * Function : "findphins()". + */ + +extern struct phins *findphins(apPhfig, insName) + struct phfig *apPhfig; + char *insName; +{ + struct phins *pIns; + + for (pIns = apPhfig->PHINS; pIns != NULL; pIns = pIns->NEXT) + if (pIns->INSNAME == insName) return (pIns); + + return (NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "findphmodel()". + */ + +extern struct phins *findphmodel(apPhfig, modelName) + struct phfig *apPhfig; + char *modelName; +{ + struct phins *pIns; + + for (pIns = apPhfig->PHINS; pIns != NULL; pIns = pIns->NEXT) + if (pIns->FIGNAME == modelName) return (pIns); + + return (NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "findlocon()". + */ + +extern struct locon *findlocon(apLofig, conName) + struct lofig *apLofig; + char *conName; +{ + struct locon *pCon; + + for (pCon = apLofig->LOCON; pCon != NULL; pCon = pCon->NEXT) + if (pCon->NAME == conName) return (pCon); + + return (NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "addloins_noSig()". + */ + +extern loins_list *addloins_noSig(apFig, asIns, apModel) + lofig_list *apFig, *apModel; + char *asIns; +{ + loins_list *pIns = NULL; + locon_list *pCon = NULL; + locon_list *pInsCon = NULL; + chain_list *pChain; + char *figName; + char *insName; + + + insName = namealloc (asIns); + figName = apModel->NAME; + + + /* Check insName unicity */ + if (strcmp (insName, "*") && FAST_MODE != 'Y') { + for (pIns = apFig->LOINS; pIns; pIns = pIns->NEXT) { + if (pIns->INSNAME == insName) { + errMBK ("defloadlophig"); + eprintf ("\n addloins_noSig impossible, "); + eprintf ("instance %s already exist in figure %s\n", + insName, apFig->NAME); + EXIT(1); + } + } + } + + + if (apFig->NAME == figName) { + errMBK ("defloadlophig"); + eprintf ("\n addloins_noSig impossible for %s,", insName); + eprintf ("\n instance model is the figure %s itself\n", figName); + EXIT(1); + } + + + pIns = (loins_list *)mbkalloc (sizeof (loins_list)); + + pIns->INSNAME = insName; + pIns->FIGNAME = figName; + pIns->LOCON = NULL; + pIns->USER = NULL; + pIns->NEXT = apFig->LOINS; + apFig->LOINS = pIns; + + + /* Update model list */ + for (pChain = apFig->MODELCHAIN; pChain; pChain = pChain->NEXT) + if (pChain->DATA == (void *)figName) break; + + if (!pChain) + apFig->MODELCHAIN = addchain (apFig->MODELCHAIN, (void *)figName); + + + for (pCon = apModel->LOCON; pCon; pCon = pCon->NEXT) { + pInsCon = (locon_list *)mbkalloc (sizeof (locon_list)); + + pInsCon->NAME = pCon->NAME; + pInsCon->DIRECTION = pCon->DIRECTION; + pInsCon->TYPE = 'I'; + /* We do not known the signals for the time beeing. */ + pInsCon->SIG = NULL; + pInsCon->ROOT = (void *)pIns; + pInsCon->USER = NULL; + pInsCon->PNODE = NULL; + pInsCon->NEXT = pIns->LOCON; + pIns->LOCON = pInsCon; + } + + pIns->LOCON = (locon_list *)reverse((chain_list *)pIns->LOCON); + + + return (pIns); +} + + +/* ------------------------------------------------------------------ + * Function : "addlosig_insCon()". + */ + +extern locon_list *addlosig_insCon(apIns, asCon, apSig) + loins_list *apIns; + losig_list *apSig; + char *asCon; +{ + locon_list *pCon; + char *sCon; + + + sCon = namealloc (asCon); + + for (pCon = apIns->LOCON; pCon != NULL; pCon = pCon->NEXT) { + if (pCon->NAME == sCon) { + pCon->SIG = apSig; + + return (pCon); + } + + } + + + if (!pCon) { + errMBK ("defloadlophig"); + eprintf ("\n addlosig_insCon impossible, "); + eprintf ("instance %s of model %s has no terminal %s.\n", + apIns->INSNAME, apIns->FIGNAME, sCon); + EXIT(1); + } + + return (pCon); +} + + +/* ------------------------------------------------------------------ + * Function : "addfeed()". + */ + +extern void addfeed (apLofig, apPhfig) + struct lofig *apLofig; + struct phfig *apPhfig; +{ + struct locon *pLocon; + struct phins *pPhins; + struct lofig *pFeedfig; + struct losig *sig, *sigVDD, *sigVSS; + struct chain *pSighead, **ppSigtail; + + + /* Find VDD & VSS signals. */ + for (sigVDD = apLofig->LOSIG; + !isvdd (getsigname (sigVDD)); sigVDD = sigVDD->NEXT); + + if (!sigVDD) { + errMBK (NULL); + eprintf ("The netlist have no VDD net.\n"); + EXIT (1); + } + + for (sigVSS = apLofig->LOSIG; + !isvss (getsigname (sigVSS)); sigVSS = sigVSS->NEXT); + + if (!sigVSS) { + errMBK (NULL); + eprintf ("The netlist have no VSS net.\n"); + EXIT (1); + } + + + /* Find the feedthru instances. */ + for (pPhins = apPhfig->PHINS; pPhins != NULL; pPhins = pPhins->NEXT) { + if (incatalogfeed (pPhins->FIGNAME)) { + pFeedfig = getlofig (pPhins->FIGNAME, 'P'); + + pSighead = NULL; + ppSigtail = &pSighead; + + /* Build the signal list. */ + for (pLocon = pFeedfig->LOCON; pLocon != NULL; pLocon = pLocon->NEXT) { + sig = NULL; + + if (isvdd (pLocon->NAME)) sig = sigVDD; + if (isvss (pLocon->NAME)) sig = sigVSS; + + if (!sig) { + errMBK (NULL); + eprintf ("\n Terminal \"%s\" of feedthru model \"%s\" is not a\n", + pLocon->NAME, + pPhins->FIGNAME); + eprintf (" power terminal!\n"); + EXIT (1); + } + + *ppSigtail = addchain (*ppSigtail, (void*)sig); + ppSigtail = &((*ppSigtail)->NEXT); + } + + /* Add the instance. */ + addloins (apLofig, pPhins->INSNAME, pFeedfig, pSighead); + } + } +} + + +/* ------------------------------------------------------------------ + * Function : "delfeed()". + */ + +extern void delfeed (apLofig) + struct lofig *apLofig; +{ + struct loins *pIns; + struct chain *pFeedIns, *pChain; + + pFeedIns = NULL; + + /* Find the feedthru instances. */ + for (pIns = apLofig->LOINS; pIns != NULL; pIns = pIns->NEXT) { + if (incatalogfeed (pIns->FIGNAME)) + pFeedIns = addchain (pFeedIns, (void*)pIns->INSNAME); + } + + + /* Remove thoses instances. */ + for (pChain = pFeedIns; pChain != NULL; pChain = pChain->NEXT) { + delloins (apLofig, (char*)(pChain->DATA)); + } + + + freechain (pFeedIns); +} + + +/* ------------------------------------------------------------------ + * Function : "checkLofig()". + */ + +extern void checkLofig(apLofig) + struct lofig *apLofig; +{ + struct loins *pIns; + struct locon *pCon; + long unassigned; + + + unassigned = 0; + + for (pIns = apLofig->LOINS; pIns != NULL; pIns = pIns->NEXT) { + for(pCon = pIns->LOCON; pCon != NULL; pCon = pCon->NEXT) { + if (!pCon->SIG) { + unassigned++; + + warnMBK ("defloadlophfig"); + wprintf ("Terminal %s of instance %s is not assigned.\n", + pCon->NAME, pIns->INSNAME); + } + } + } + + if (unassigned) { + errMBK ("defloadlophig"); + eprintf ("There is %ld terminals unassigned.\n", unassigned); + EXIT (1); + } +} + + +/* ------------------------------------------------------------------ + * Function : "copyUpCALU()". + */ + +extern void copyUpCALU(apLofig, apPhfig, aExit) + struct lofig *apLofig; + struct phfig *apPhfig; + long aExit; +{ + long flag; + struct locon *pLocon, *pLoconIns; + struct losig *pLosig; + struct chain *pChain, *pChainLocon; + struct loins *pLoins; + struct phseg *pPhseg; + struct phins *pPhins; + struct phfig *pPhfigIns; + char *sigName; + long X1, Y1, X2, Y2; + + + lofigchain (apLofig); + + + for (pLocon = apLofig->LOCON; pLocon != NULL; pLocon = pLocon->NEXT) { + pLosig = pLocon->SIG; + + flag = FALSE; + + for(pChain = pLosig->NAMECHAIN; pChain != NULL; pChain = pChain->NEXT) { + sigName = (char*)pChain->DATA; + + if (isvdd (sigName) || isvss (sigName)) continue; + + /* Looks if the terminal already have physical segments in CALU on + * the top level of the design. + * This is a bit slow but I have no time for optimization. + */ + for (pPhseg = apPhfig->PHSEG; pPhseg != NULL; pPhseg = pPhseg->NEXT) { + if ( (pPhseg->NAME == sigName) + && (isCALU(pPhseg->LAYER)) ) { + flag = TRUE; + break; + } + } + + + if (!flag) { + /* No CALU in the top level design. We have to copy up the + * terminals from the instances (in fact there should be only one + * instance). + */ + flag = FALSE; + + pChainLocon = (chain_list*)(getptype (pLosig->USER, + LOFIGCHAIN)->DATA); + + for (; pChainLocon != NULL; pChainLocon = pChainLocon->NEXT) { + /* Copy only the first CALU segment to avoid separate segments + * for one equi (this is not valid for lynx). + */ + pLoconIns = (locon_list*) pChainLocon->DATA; + + if (pLoconIns->TYPE == INTERNAL) { + pLoins = (loins_list*)(pLoconIns->ROOT); + + pPhfigIns = getphfig (pLoins->FIGNAME, 'A'); + pPhins = getphins (apPhfig, pLoins->INSNAME); + + for (pPhseg = pPhfigIns->PHSEG; + pPhseg != NULL; pPhseg = pPhseg->NEXT) { + if ( (pPhseg->NAME == pLoconIns->NAME) + && (isCALU(pPhseg->LAYER)) ) { + flag = TRUE; + + xyflat ( &X1 , &Y1 , + pPhseg->X1 , pPhseg->Y1 , + pPhins->XINS , pPhins->YINS, + pPhfigIns->XAB1, pPhfigIns->YAB1, + pPhfigIns->XAB2, pPhfigIns->YAB2, + pPhins->TRANSF); + + xyflat ( &X2 , &Y2 , + pPhseg->X2 , pPhseg->Y2 , + pPhins->XINS , pPhins->YINS, + pPhfigIns->XAB1, pPhfigIns->YAB1, + pPhfigIns->XAB2, pPhfigIns->YAB2, + pPhins->TRANSF); + + addphseg (apPhfig, + pPhseg->LAYER, + pPhseg->WIDTH, + X1, Y1, X2, Y2, + sigName + ); + } + } + } + } /* End of "for(pChainLocon...)". */ + + if (!flag) { + if (aExit) { + errMBK ("copyUpCALU"); + eprintf ("\n No instances CALUx for terminal \"%s\".\n", + pLocon->NAME); + EXIT (1); + } else { + warnMBK ("copyUpCALU"); + wprintf ("\n No instances CALUx for terminal \"%s\".\n", + pLocon->NAME); + } + } + } /* End of "for(pChain...)". */ + } + } +} + + +/* ------------------------------------------------------------------ + * Function : "addloseg()". + */ + +extern struct eLoseg_s *addloseg (apHead, aType, apMBKobj) + struct eLoseg_s *apHead; + long aType; + void *apMBKobj; +{ + struct eLoseg_s *pLoseg; + struct ptype **ppUser; + + + ppUser = NULL; + pLoseg = (struct eLoseg_s*)mbkalloc (sizeof (struct eLoseg_s)); + + switch (aType) { + case LOSEG_VIA: ppUser = &(((struct phvia*)apMBKobj)->USER); break; + case LOSEG_CON: ppUser = &(((struct phcon*)apMBKobj)->USER); break; + case LOSEG_SEG: + case LOSEG_SEGCON: ppUser = &(((struct phseg*)apMBKobj)->USER); break; + default: + wprinth ("addloseg"); + eprintf ("\n Bad loseg type id %ld.\n", aType); + EXIT (1); + } + + *ppUser = addptype (*ppUser, PTYPE_LOSEG, (void*)pLoseg); + + pLoseg->type = aType; + pLoseg->MBKobj = apMBKobj; + pLoseg->next = apHead; + + + return (pLoseg); +} + + +/* ------------------------------------------------------------------ + * Function : "delloseg()". + */ + +extern struct eLoseg_s *delloseg (apLoseg) + struct eLoseg_s *apLoseg; +{ + struct ptype **ppUser; + + + ppUser = NULL; + + switch (apLoseg->type) { + case LOSEG_VIA: ppUser = &(((struct phvia*)apLoseg->MBKobj)->USER); break; + case LOSEG_CON: ppUser = &(((struct phcon*)apLoseg->MBKobj)->USER); break; + case LOSEG_SEG: + case LOSEG_SEGCON: ppUser = &(((struct phseg*)apLoseg->MBKobj)->USER); break; + default: + wprinth ("delloseg"); + eprintf ("\n Bad loseg type id %ld.\n", apLoseg->type); + EXIT (1); + } + + *ppUser = delptype (*ppUser, PTYPE_LOSEG); + + return (apLoseg->next); +} + + +/* ------------------------------------------------------------------ + * Function : "addtloseg()". + */ + +extern struct tLoseg_s *addtloseg (apPhfig) + struct phfig *apPhfig; +{ + struct tLoseg_s *ptLoseg; + int tLoseg_size; + + + if (getptype (apPhfig->USER, PTYPE_TLOSEG)) { + eprinth ("addtloseg"); + eprintf ("\n Attempt to re-create loseglist on figure \"%s\".", + apPhfig->NAME); + EXIT (1); + } + + + ptLoseg = (struct tLoseg_s*)mbkalloc (sizeof (struct tLoseg_s)); + + apPhfig->USER = addptype (apPhfig->USER, PTYPE_TLOSEG, (void*)ptLoseg); + + tLoseg_size = sizeof (struct eLoseg_s*) * TLOSEG_SIZE; + + ptLoseg->sigNB = 0; + ptLoseg->tSize = TLOSEG_SIZE; + ptLoseg->tHT = createauthtable (TLOSEG_SIZE); + ptLoseg->tAccess = (long*) malloc (sizeof (long) * TLOSEG_SIZE); + ptLoseg->tFlags = (long*) malloc (sizeof (long) * TLOSEG_SIZE); + ptLoseg->tLoseg = (struct eLoseg_s**) malloc (tLoseg_size); + + memset (ptLoseg->tLoseg , 0, tLoseg_size); + memset (ptLoseg->tAccess, 0, sizeof(long) * TLOSEG_SIZE); + memset (ptLoseg->tFlags , 0, sizeof(long) * TLOSEG_SIZE); + + ptLoseg->tMVIA = NULL; + + + return (ptLoseg); +} + + +/* ------------------------------------------------------------------ + * Function : "gettloseg()". + */ + +extern struct tLoseg_s *gettloseg (apPhfig) + struct phfig *apPhfig; +{ + struct ptype *pType; + + pType = getptype (apPhfig->USER, PTYPE_TLOSEG); + + if (pType) return ((struct tLoseg_s*)(pType->DATA)); + + return (NULL); +} + + +/* ------------------------------------------------------------------ + * Function : "gettlosegitem()". + */ + +extern struct authelem *gettlosegitem (apTLoseg, asKey) + struct tLoseg_s *apTLoseg; + char *asKey; +{ + struct authelem *pElem; + size_t eLoseg_size; + long sigIndex; + + + eLoseg_size = sizeof (struct eLoseg_s*); + + pElem = searchauthelem (apTLoseg->tHT, asKey); + + if (!pElem) { + sigIndex = apTLoseg->sigNB; + + __DBG( + fflush (stdout); + fprintf (stderr, "Adding loseg \"%s\" (id %ld)\n", asKey, sigIndex); + ) + + if (apTLoseg->sigNB >= apTLoseg->tSize) { + apTLoseg->tSize += TLOSEG_SIZE; + + /* Re-allocate the 'tLoseg' table. */ + apTLoseg->tLoseg = (struct eLoseg_s**)realloc ( + apTLoseg->tLoseg, eLoseg_size * apTLoseg->tSize); + + if (!apTLoseg->tLoseg) { + eprinth ("phsegchain"); + eprintf ("\n Not enougth memory to re-allocate \"tLoseg\".\n"); + EXIT (1); + } + + memset (apTLoseg->tLoseg + (apTLoseg->tSize - TLOSEG_SIZE), + 0, eLoseg_size * TLOSEG_SIZE); + + + /* Re-allocate the 'tAccess' & 'tFlags' tables. */ + apTLoseg->tAccess = (long*)realloc ( + apTLoseg->tAccess, sizeof(long) * apTLoseg->tSize); + apTLoseg->tFlags = (long*)realloc ( + apTLoseg->tFlags , sizeof(long) * apTLoseg->tSize); + + if (!apTLoseg->tAccess || !apTLoseg->tFlags) { + eprinth ("phsegchain"); + eprintf ("\n Not enougth memory to re-allocate \"tLoseg\".\n"); + EXIT (1); + } + + memset (apTLoseg->tAccess + (apTLoseg->tSize - TLOSEG_SIZE), + 0, sizeof(long) * TLOSEG_SIZE); + } + + pElem = addauthelem (apTLoseg->tHT, asKey, sigIndex); + + apTLoseg->sigNB += 1; + } + + + return (pElem); +} + + +/* ------------------------------------------------------------------ + * Function : "getlosegname()". + */ + +static char *getlosegname (apLoseg) + struct eLoseg_s *apLoseg; +{ + switch (apLoseg->type) { + case LOSEG_SEG: return (((struct phseg*)(apLoseg->MBKobj))->NAME); + case LOSEG_VIA: return (((struct phvia*)(apLoseg->MBKobj))->NAME); + case LOSEG_CON: return (((struct phcon*)(apLoseg->MBKobj))->NAME); + } + + + return ("Invalid loseg object! This should never happens!\n"); +} + + +/* ------------------------------------------------------------------ + * Function : "freeloseg()". + */ + +extern void freeloseg (apPhfig) + struct phfig *apPhfig; +{ + struct phseg *pPhseg; + struct ptype *pType; + struct tLoseg_s *ptLoseg; + struct eMVIA_s *pMVIA, *pMVIA_next; + + + for (pPhseg = apPhfig->PHSEG; pPhseg != NULL; pPhseg = pPhseg->NEXT) { + if ((pType = getptype (pPhseg->USER, PTYPE_LOSEG))) { + mbkfree (pType->DATA); + pPhseg->USER = delptype (pPhseg->USER, PTYPE_LOSEG); + } + } + + + + if ((pType = getptype (apPhfig->USER, PTYPE_TLOSEG))) { + ptLoseg = (struct tLoseg_s*)(pType->DATA); + + destroyauthtable (ptLoseg->tHT); + free (ptLoseg->tLoseg); + + for (pMVIA = ptLoseg->tMVIA; pMVIA != NULL;) { + pMVIA_next = pMVIA->next; + + mbkfree (pMVIA); + + pMVIA = pMVIA_next; + } + + + mbkfree (ptLoseg->tAccess); + mbkfree (ptLoseg->tFlags); + mbkfree (ptLoseg); + + apPhfig->USER = delptype (apPhfig->USER, PTYPE_TLOSEG); + } +} + + +/* ------------------------------------------------------------------ + * Function : "addmvia()". + */ + +extern struct eMVIA_s *addmvia (apHead, apVIA) + struct eMVIA_s *apHead; + struct phvia *apVIA; +{ + struct eMVIA_s *pMVIA; + + + pMVIA = (struct eMVIA_s*)mbkalloc (sizeof (struct eMVIA_s)); + + pMVIA->type = apVIA->TYPE; + pMVIA->width = apVIA->DX; + pMVIA->height = apVIA->DY; + pMVIA->next = apHead; + + + return (pMVIA); +} + + +/* ------------------------------------------------------------------ + * Function : "getmvia()". + */ + +extern struct eMVIA_s *getmvia (apHead, apVIA) + struct eMVIA_s *apHead; + struct phvia *apVIA; +{ + struct eMVIA_s *pMVIA; + + + for (pMVIA = apHead; pMVIA != NULL; pMVIA = pMVIA->next) { + if ( (pMVIA->type == apVIA->TYPE) + && (pMVIA->width == apVIA->DX ) + && (pMVIA->height == apVIA->DY )) + break; + } + + return (pMVIA); +} + + +/* ------------------------------------------------------------------ + * Function : "buildtsigalias()". + */ + +static void buildtsigalias(apLosig) + struct losig *apLosig; +{ + struct losig *pLosig; + struct chain *pChain; + long sigNumber; + + + if (LV_htSigAlias || LV_tSigAlias) { + eprinth ("buildtsigalias"); + eprintf ("\n Attempt to re-allocate the signal alias name table.\n"); + EXIT (1); + } + + + sigNumber = 0; + + for (pLosig = apLosig; pLosig != NULL; pLosig = pLosig->NEXT) sigNumber++; + + + LV_tSigAlias = (struct sigalias_s*) mbkalloc ( + sigNumber * sizeof (struct sigalias_s)); + LV_htSigAlias = createauthtable (sigNumber); + + + sigNumber = 0; + + for (pLosig = apLosig; pLosig != NULL; pLosig = pLosig->NEXT) { + LV_tSigAlias[sigNumber].name = getsigname (pLosig); + LV_tSigAlias[sigNumber].flags = 0L; + + __DBG( fprintf (stderr, " o Main signal name := \"%s\".\n", + LV_tSigAlias[sigNumber].name); ) + + for (pChain = pLosig->NAMECHAIN; pChain != NULL; pChain = pChain->NEXT) { + addauthelem (LV_htSigAlias, pChain->DATA, sigNumber); + + __DBG( + fprintf (stderr, " - Alias := \"%s\".\n", (char*)pChain->DATA); ) + + if (pChain != pLosig->NAMECHAIN) + LV_tSigAlias[sigNumber].flags = F_HAS_SUBNET; + } + + sigNumber++; + } +} + + +/* ------------------------------------------------------------------ + * Function : "freetsigalias()". + */ + +static void freetsigalias() +{ + if (!LV_htSigAlias) destroyauthtable (LV_htSigAlias); + if (!LV_tSigAlias) mbkfree (LV_tSigAlias); + + LV_htSigAlias = NULL; + LV_tSigAlias = NULL; +} + + +/* ------------------------------------------------------------------ + * Function : "matchsigname()". + */ + +static struct sigalias_s *matchsigname(aSegName) + char *aSegName; +{ + static struct sigalias_s noSigAlias; + authelem *pElem; + char **tSegAlias; + long iSegAlias; + + + tSegAlias = makesegnamelist (aSegName); + + for (iSegAlias = 0; tSegAlias[iSegAlias] != NULL; iSegAlias++) { + pElem = searchauthelem (LV_htSigAlias, tSegAlias[iSegAlias]); + + if (pElem) + return (&(LV_tSigAlias[pElem->VALUE])); + } + + /* This name doesn't match any net name (losig). + * This is probably an error. + */ + noSigAlias.name = aSegName; + noSigAlias.flags = 0L; + + return (&noSigAlias); +} + + +/* ------------------------------------------------------------------ + * Function : "phsegchain()". + */ + +extern void phsegchain(apLofig, apPhfig) + struct lofig *apLofig; + struct phfig *apPhfig; +{ + struct tLoseg_s *ptLoseg; + struct phseg *pPhseg; + struct phvia *pPhvia; + struct phcon *pPhcon; + struct sigalias_s *pSigAlias; + authelem *pElem; + + + ptLoseg = addtloseg (apPhfig); + + + /* Building alias table name. */ + buildtsigalias (apLofig->LOSIG); + + + /* Sorting segments by names. */ + for (pPhseg = apPhfig->PHSEG; pPhseg != NULL; pPhseg = pPhseg->NEXT) { + __DBG( + fprintf (stdout, "seg (%ld,%ld) (%ld,%ld) width %ld layer id %d\n", + pPhseg->X1, + pPhseg->Y1, + pPhseg->X2, + pPhseg->Y2, + pPhseg->WIDTH, + (int)pPhseg->LAYER); + fflush (stdout); + ) + if (pPhseg->NAME == NULL) { + eprinth ("phsegchain"); + eprintf ("\n Segment (%ld,%ld) (%ld,%ld) width %ld layer id %d", + pPhseg->X1, + pPhseg->Y1, + pPhseg->X2, + pPhseg->Y2, + pPhseg->WIDTH, + (int)pPhseg->LAYER); + eprintf ("\n doesn't have a name.\n"); + EXIT (1); + } + + if (pPhseg->NAME[0] == (char)0) { + eprinth ("phsegchain"); + eprintf ("\n Segment (%ld,%ld) (%ld,%ld) width %ld layer id %d", + pPhseg->X1, + pPhseg->Y1, + pPhseg->X2, + pPhseg->Y2, + pPhseg->WIDTH, + (int)pPhseg->LAYER); + eprintf ("\n have an empty string for name.\n"); + EXIT (1); + } + + if (isobs (pPhseg)) continue; + + pSigAlias = matchsigname (pPhseg->NAME); + + pElem = gettlosegitem (ptLoseg, pSigAlias->name); + + ptLoseg->tLoseg[pElem->VALUE] = addloseg (ptLoseg->tLoseg[pElem->VALUE], + LOSEG_SEG, + (void*)pPhseg); + } + + + /* Sorting vias by names. */ + for (pPhvia = apPhfig->PHVIA; pPhvia != NULL; pPhvia = pPhvia->NEXT) { + if (pPhvia->NAME == NULL) { + eprinth ("phsegchain"); + eprintf ("\n VIA (%ld,%ld) type id %d", + pPhvia->XVIA, + pPhvia->YVIA, + (int)pPhvia->TYPE); + eprintf ("\n doesn't have a name.\n"); + EXIT (1); + } + + if (!getmvia (ptLoseg->tMVIA, pPhvia)) { + ptLoseg->tMVIA = addmvia (ptLoseg->tMVIA, pPhvia); + __DBG( + fflush (stdout); + fprintf (stderr, "tMVIA := 0x%08lx\n", (unsigned long)ptLoseg->tMVIA); + fflush (stderr); + ) + } + + pSigAlias = matchsigname (pPhvia->NAME); + + pElem = gettlosegitem (ptLoseg, pSigAlias->name); + + ptLoseg->tLoseg[pElem->VALUE] = addloseg (ptLoseg->tLoseg[pElem->VALUE], + LOSEG_VIA, + (void*)pPhvia); + + __DBG( + fprintf (stderr, " - New loseg := 0x%08ld\n", + (unsigned long)ptLoseg->tLoseg[pElem->VALUE]); + ) + } + + + /* Sorting terminals by names. */ + for (pPhcon = apPhfig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) { + if (pPhcon->NAME == NULL) { + eprinth ("phsegchain"); + eprintf ("\n CON (%ld,%ld) type id %d", + pPhcon->XCON, + pPhcon->YCON, + (int)pPhseg->TYPE); + eprintf ("\n doesn't have a name.\n"); + EXIT (1); + } + + pSigAlias = matchsigname (pPhcon->NAME); + + pElem = gettlosegitem (ptLoseg, pSigAlias->name); + + ptLoseg->tLoseg[pElem->VALUE] = addloseg (ptLoseg->tLoseg[pElem->VALUE], + LOSEG_CON, + (void*)pPhcon); + + __DBG( + fprintf (stderr, " - New loseg := 0x%08ld\n", + (unsigned long)ptLoseg->tLoseg[pElem->VALUE]); + ) + } + + + freetsigalias (); + + __DBG( + fprintf (stderr, "ptLoseg := 0x%08lx\n", (unsigned long)ptLoseg); + fflush (stderr); + ) +} + + +/* ------------------------------------------------------------------ + * Function : "getloseglist()". + */ + +extern struct eLoseg_s *getloseglist(apPhfig, aName) + struct phfig *apPhfig; + char *aName; +{ + struct tLoseg_s *ptLoseg; + struct eLoseg_s *pLoseg; + struct ptype *pType; + authelem *pElem; + + + if (!(pType = getptype (apPhfig->USER, PTYPE_TLOSEG))) { + /* + * eprinth ("getloseglist"); + * eprintf ("\n Figure \"%s\" doesn't have a loseg list.\n", + * apPhfig->NAME); + * EXIT (1); + */ + return (NULL); + } + ptLoseg = (struct tLoseg_s*)(pType->DATA); + + + pLoseg = NULL; + + pElem = searchauthelem (ptLoseg->tHT, aName); + + if (pElem) { + __DBG( + fflush (stdout); + fprintf (stderr, "getloseglist:Loseg found (id %ld)\n", pElem->VALUE); + ) + + pLoseg = ptLoseg->tLoseg [pElem->VALUE]; + ptLoseg->tAccess[pElem->VALUE]++; + } + + + return (pLoseg); +} + + +/* ------------------------------------------------------------------ + * Function : "checklosegaccess()". + */ + +extern void checklosegaccess(apPhfig) + struct phfig *apPhfig; +{ + struct tLoseg_s *ptLoseg; + struct ptype *pType; + long iLoseg; + long flag; + + + if (!(pType = getptype (apPhfig->USER, PTYPE_TLOSEG))) { + /* + * eprinth ("getloseglist"); + * eprintf ("\n Figure \"%s\" doesn't have a loseg list.\n", + * apPhfig->NAME); + * EXIT (1); + */ + return; + } + ptLoseg = (struct tLoseg_s*)(pType->DATA); + + + flag = FALSE; + for (iLoseg = 0; iLoseg < ptLoseg->sigNB; iLoseg++) { + if (ptLoseg->tAccess[iLoseg] == 0) { + if (!flag) { + /* Print the head error message. */ + flag = TRUE; + + eprinth (NULL); + eprintf ("The following physical net segments are not in the"); + eprintf (" netlist :\n"); + flag = TRUE; + } + + eprintf ("- \"%s\".\n", getlosegname (ptLoseg->tLoseg[iLoseg])); + } + } + + + if (flag) EXIT (1); +} + + +/* ------------------------------------------------------------------ + * Function : "shiftphfig()". + */ + +extern void shiftphfig(apPhfig, DX, DY) + struct phfig *apPhfig; + long DX, DY; +{ + struct phseg *pSeg; + struct phins *pIns; + struct phvia *pVIA; + struct phref *pRef; + struct phcon *pCon; + + + apPhfig->XAB1 -= DX; + apPhfig->XAB2 -= DX; + apPhfig->YAB1 -= DY; + apPhfig->YAB2 -= DY; + + + for (pSeg = apPhfig->PHSEG; pSeg != NULL; pSeg = pSeg->NEXT) { + pSeg->X1 -= DX; + pSeg->X2 -= DX; + pSeg->Y1 -= DY; + pSeg->Y2 -= DY; + } + + for (pIns = apPhfig->PHINS; pIns != NULL; pIns = pIns->NEXT) { + pIns->XINS -= DX; + pIns->YINS -= DY; + } + + for (pVIA = apPhfig->PHVIA; pVIA != NULL; pVIA = pVIA->NEXT) { + pVIA->XVIA -= DX; + pVIA->YVIA -= DY; + } + + for (pRef = apPhfig->PHREF; pRef != NULL; pRef = pRef->NEXT) { + pRef->XREF -= DX; + pRef->YREF -= DY; + } + + for (pCon = apPhfig->PHCON; pCon != NULL; pCon = pCon->NEXT) { + pCon->XCON -= DX; + pCon->YCON -= DY; + } +} diff --git a/alliance/src/sea/src/util_Power.c b/alliance/src/sea/src/util_Power.c new file mode 100644 index 00000000..5e121f20 --- /dev/null +++ b/alliance/src/sea/src/util_Power.c @@ -0,0 +1,498 @@ +/* + * $Id: util_Power.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./util_Power.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" +# include "debugoff.h" + + +/* ------------------------------------------------------------------ + * Local variables (prefix 'LV_'). + */ + + static long LV_XAB1; + static long LV_YAB1; + static long LV_XAB2; + static long LV_YAB2; + + +/* ---------------------------------------------------------------------- + * Local functions declarations. + */ + + static int onSlice __FP((long aY)); + static void setPowerAB __FP((long XAB1, long YAB1, + long XAB2, long YAB2)); + + +/* + * /--------------------------------------------------------------------\ + * | Functions Definitions | + * \--------------------------------------------------------------------/ + */ + + +/* ---------------------------------------------------------------------- + * Function : "setPowerAB()". + */ + +static void setPowerAB(XAB1, YAB1, XAB2, YAB2) + long XAB1, YAB1, XAB2, YAB2; +{ + LV_XAB1 = XAB1; + LV_YAB1 = YAB1; + LV_XAB2 = XAB2; + LV_YAB2 = YAB2; +} + + + +/* ---------------------------------------------------------------------- + * Function : "onSlice()". + */ + +static int onSlice(aY) + long aY; +{ + if (aY < LV_YAB1) return (FALSE); + if (aY > LV_YAB2) return (FALSE); + + if (!(((aY - MBK_WIDTH_VDD / 2) - LV_YAB1) % MBK_Y_SLICE)) return (TRUE); + if (!(((aY + MBK_WIDTH_VDD / 2) - LV_YAB1) % MBK_Y_SLICE)) return (TRUE); + + if (!(((aY - MBK_WIDTH_VSS / 2) - LV_YAB1) % MBK_Y_SLICE)) return (TRUE); + if (!(((aY + MBK_WIDTH_VSS / 2) - LV_YAB1) % MBK_Y_SLICE)) return (TRUE); + + return (FALSE); +} + +/* ---------------------------------------------------------------------- + * Function : "addPow()". + */ + +extern ePow_t *addPow(applPow, aY, aW, aName, aType, aDir) + ePow_t **applPow; + long aY; + long aW; + char *aName; + char aType; + char aDir; +{ + ePow_t *pPow, **ppPow; + + + pPow = (ePow_t*)mbkalloc(sizeof(ePow_t)); + pPow->y = aY; + pPow->w = aW; + pPow->flags = 0; + pPow->inter = NULL; + + switch(aDir) { + case C_POWER_VERTICAL: + pPow->xMin = LV_YAB1; + pPow->xMax = LV_YAB2; + pPow->min = LV_YAB2; + pPow->max = LV_YAB1; + break; + default: + case C_POWER_HORIZONTAL: + pPow->xMin = LV_XAB1; + pPow->xMax = LV_XAB2; + pPow->min = LV_XAB2; + pPow->max = LV_XAB1; + break; + } + + pPow->Name = namealloc(aName); + pPow->Type = aType; + + + /* Insert in the ordered list. */ + for(ppPow = applPow ; *ppPow != NULL ; ppPow = &((*ppPow)->Next)) { + if ((*ppPow)->y >= pPow->y) { + pPow->Next = *ppPow; + *ppPow = pPow; + break; + } + } + + + /* The list is empty or the element is the last one. */ + if (*ppPow == (ePow_t*)NULL) { + pPow->Next = *ppPow; + *ppPow = pPow; + } + + + return(pPow); +} + + +/* ---------------------------------------------------------------------- + * Function : "freePow()". + */ + +extern void freePow(aplPow) + struct ePow_s *aplPow; +{ + struct ePow_s *pDel, *pNext; + + + for (pDel = aplPow; pDel != NULL; ) { + pNext = pDel->Next; + + freeinter (pDel->inter); + mbkfree (pDel); + + pDel = pNext; + } +} + + +/* ---------------------------------------------------------------------- + * Function : "getPow()". + */ + +extern ePow_t *getPow(aplPow, aY) + ePow_t *aplPow; + long aY; +{ + ePow_t *pPow; + + + for( pPow = aplPow ; pPow != NULL ; pPow = pPow->Next ) + if (pPow->y == aY) return( pPow ); + + return( NULL ); +} + + +/* ---------------------------------------------------------------------- + * Function : "mergeXPow()". + */ + +extern void mergeXPow(apPow, axMin, axMax, aW) + ePow_t *apPow; + long axMin, axMax, aW; +{ + if (aW == apPow->w) + apPow->inter = addinter (apPow->inter, axMin, axMax); + + apPow->min = m_Min(apPow->min, axMin); + apPow->max = m_Max(apPow->max, axMax); +} + + +/* ---------------------------------------------------------------------- + * Function : "buildPow()". + */ + +extern ePow_t *buildPow(apPhfig, aLayer, aDir, asSuffix) + struct phfig *apPhfig; + char aLayer; + char aDir; + char *asSuffix; +{ + ePow_t **pplPow, *plPow, *pPow; + phseg_list *pPhseg; + phcon_list *pPhcon; + char type; + char ORIENT1, ORIENT2, *sDir1, *sDir2; + long X1, X2, Y1, Y2; + + + setPowerAB (apPhfig->XAB1, apPhfig->YAB1, + apPhfig->XAB2, apPhfig->YAB2); + + + switch(aDir) { + case C_POWER_VERTICAL: + sDir1 = "vertical"; + sDir2 = "NORTH/SOUTH"; + ORIENT1 = NORTH; + ORIENT2 = SOUTH; + break; + default: + case C_POWER_HORIZONTAL: + sDir1 = "horizontal"; + sDir2 = "EAST/WEST"; + ORIENT1 = EAST; + ORIENT2 = WEST; + break; + } + + + pplPow = &plPow; + *pplPow = NULL; + + + /* Find power terminals among CALUx segments (new convention). */ + for(pPhseg = apPhfig->PHSEG ; pPhseg != NULL ; pPhseg = pPhseg->NEXT) { + type = C_POWER_ISNONE; + + if (isvdd(pPhseg->NAME)) type = C_POWER_ISVDD; + if (isvss(pPhseg->NAME)) type = C_POWER_ISVSS; + + switch(aDir) { + case C_POWER_VERTICAL: + Y1 = pPhseg->X1; + Y2 = pPhseg->X2; + X1 = pPhseg->Y1; + X2 = pPhseg->Y2; + break; + default: + case C_POWER_HORIZONTAL: + Y1 = pPhseg->Y1; + Y2 = pPhseg->Y2; + X1 = pPhseg->X1; + X2 = pPhseg->X2; + break; + } + + if (type != C_POWER_ISNONE) { + if (cmpALU(aLayer, pPhseg->LAYER) & F_CALU) { + if (Y1 != Y2) { + wprinth(NULL); + wprintf("\n In figure \"%s\" :", apPhfig->NAME); + wprintf("\n CALU1 Power segment \"%s\" at (%d,%d)", + pPhseg->NAME, + MBKUNSCALE (pPhseg->X1), + MBKUNSCALE (pPhseg->Y1)); + wprintf(" is not %s.\n", sDir1); + continue; + } + + if (aDir == C_POWER_HORIZONTAL) { + if (!onSlice(Y1)) { + wprinth(NULL); + wprintf("\n In figure \"%s\" :", apPhfig->NAME); + wprintf("\n CALU1 Power segment \"%s\" at (%d,%d)", + pPhseg->NAME, + MBKUNSCALE (pPhseg->X1), + MBKUNSCALE (pPhseg->Y1)); + wprintf(" is not on a slice boundary."); + wprintf("\n (valide slices boundaries are"); + wprintf(" ((n * %ld) - %ld) or" , Y_SLICE, WIDTH_VSS / 2); + wprintf(" ((n * %ld) + %ld) )\n" , Y_SLICE, WIDTH_VSS / 2); + continue; + } + } + + if ((pPow = getPow(plPow, Y1)) == NULL) { + pPow = addPow(pplPow , + Y1 , + pPhseg->WIDTH, + pPhseg->NAME , + type , + aDir ); + } + + if (pPhseg->NAME != pPow->Name) { + eprinth(NULL); + eprintf("\n In figure \"%s\" :", apPhfig->NAME); + eprintf("\n CALU1 Power segment \"%s\" at (%d,%d)\n", + pPhseg->NAME, + MBKUNSCALE (pPhseg->X1), + MBKUNSCALE (pPhseg->Y1)); + eprintf(" conflict with \"%s\" power line at %d.\n", + pPow->Name, + pPow->y ); + EXIT(1); + } + + mergeXPow(pPow, X1, X2, pPhseg->WIDTH); + } + } + } /* End of "pPhseg" loop. */ + + + /* Find power terminals among terminals (for backward compatibility). */ + for(pPhcon = apPhfig->PHCON ; pPhcon != NULL ; pPhcon = pPhcon->NEXT) { + type = C_POWER_ISNONE; + + if (isvdd(pPhcon->NAME)) type = C_POWER_ISVDD; + if (isvss(pPhcon->NAME)) type = C_POWER_ISVSS; + + switch(aDir) { + case C_POWER_VERTICAL: + Y1 = pPhcon->XCON; + X1 = pPhcon->YCON; + break; + default: + case C_POWER_HORIZONTAL: + Y1 = pPhcon->YCON; + X1 = pPhcon->XCON; + break; + } + + if (type != C_POWER_ISNONE) { + if (cmpALU(aLayer, pPhcon->LAYER)) { + if ( (pPhcon->ORIENT != ORIENT1) + && (pPhcon->ORIENT != ORIENT2)) { + eprinth(NULL); + eprintf("\n In figure \"%s\" :", apPhfig->NAME); + eprintf("\n ALU1 Power terminal \"%s\" at (%d,%d)", + pPhcon->NAME, + MBKUNSCALE (pPhcon->XCON), + MBKUNSCALE (pPhcon->YCON)); + eprintf(" is not on %s side.\n", sDir2); + EXIT(1); + } + + if (aDir == C_POWER_HORIZONTAL) { + if (!onSlice(pPhcon->YCON)) { + eprinth(NULL); + eprintf("\n In figure \"%s\" :", apPhfig->NAME); + eprintf("\n ALU1 Power terminal \"%s\" at (%d,%d)", + pPhcon->NAME, + MBKUNSCALE (pPhcon->XCON), + MBKUNSCALE (pPhcon->YCON)); + eprintf(" is not on a slice boundary."); + eprintf("\n (valide slices boundaries are"); + eprintf(" ((n * %ld) - %ld) or" , Y_SLICE, WIDTH_VSS / 2); + eprintf(" ((n * %ld) + %ld) )\n" , Y_SLICE, WIDTH_VSS / 2); + EXIT(1); + } + } + + if ((pPow = getPow(plPow, Y1)) == NULL) { + pPow = addPow(pplPow , + Y1 , + pPhcon->WIDTH, + pPhcon->NAME , + type , + aDir ); + } + + if (pPhcon->NAME != pPow->Name) { + eprinth(NULL); + eprintf("\n In figure \"%s\" :", apPhfig->NAME); + eprintf("\n ALU1 Power terminal \"%s\" at (%d,%d)\n", + pPhcon->NAME, + MBKUNSCALE (pPhcon->XCON), + MBKUNSCALE (pPhcon->YCON)); + eprintf(" conflict with \"%s\" power line at %d.\n", + pPow->Name, + pPow->y ); + EXIT(1); + } + + mergeXPow(pPow, X1, X1, pPhcon->WIDTH); + } + } + } /* End of "pPhcon" loop. */ + + + /* Look if the power lines are complete. */ + for (pPow = plPow; pPow != NULL; pPow = pPow->Next) { + if ( (pPow->inter->len == 1) + && (pPow->inter->min == pPow->xMin) + && (pPow->inter->max == pPow->xMax)) { + pPow->flags |= F_POWER_COMPLETE; + __DBG( printf ("powerline at %ld is complete.\n", pPow->y); ) + } + } + + + return (plPow); +} + + +/* ---------------------------------------------------------------------- + * Function : "powToCon()". + */ + +extern void powToCon(apPhfig, aLayer, aDir, aplPow, aFlags) + struct phfig *apPhfig; + char aLayer; + char aDir; + struct ePow_s *aplPow; + long aFlags; +{ + struct ePow_s *pPow; + char *conName; + long w, y, skipFlag; + + + for (pPow = aplPow; pPow != NULL; pPow = pPow->Next) { + skipFlag = FALSE; + + switch (pPow->Type) { + default: + case C_POWER_ISVSS: conName = "vss"; break; + case C_POWER_ISVDD: conName = "vdd"; break; + } + + w = pPow->w; + y = pPow->y; + + if (aFlags & F_POWER_MERGE) { + if ( (pPow->Next != NULL) + && (pPow->Next->y == pPow->y + MBKSCALE(6))) { + skipFlag = TRUE; + + w = MBKSCALE(12); + y += MBKSCALE(3); + } + } + + if (aDir == C_POWER_HORIZONTAL) { + if (pPow->flags & F_POWER_COMPLETE) { + addphcon (apPhfig, + WEST, + conName, + pPow->xMin, + y, + aLayer, + w); + } + + if (pPow->flags & F_POWER_COMPLETE) { + addphcon (apPhfig, + EAST, + conName, + pPow->xMax, + y, + aLayer, + w); + } + } else { + if (pPow->flags & F_POWER_COMPLETE) { + addphcon (apPhfig, + SOUTH, + conName, + y, + pPow->xMin, + aLayer, + w); + } + + if (pPow->flags & F_POWER_COMPLETE) { + addphcon (apPhfig, + NORTH, + conName, + y, + pPow->xMax, + aLayer, + w); + } + } + + if (skipFlag) pPow = pPow->Next; + } +} diff --git a/alliance/src/sea/src/util_RTU.c b/alliance/src/sea/src/util_RTU.c new file mode 100644 index 00000000..77da4766 --- /dev/null +++ b/alliance/src/sea/src/util_RTU.c @@ -0,0 +1,593 @@ + +/* + * $Id: util_RTU.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./util_RTU.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" +# include "debugoff.h" + + +# define LAYERS_NUMBER 6 +# define LAYERS_ALIAS 3 +# define TRACK_PITCH MBKSCALE(5) +# define F_PITCH_INF 0x00000001 +# define F_PITCH_SUP 0x00000002 +# define HT_TERM_SIZE 1024 + + +# define STRING_OBSTACLE "obs" + + +/* ------------------------------------------------------------------ + * Internal types. + */ + + typedef struct obsTrack_s { + long min; + long max; + } obsTrack_t; + + +/* ------------------------------------------------------------------ + * Local variables (prefix 'LV_'). + */ + + static struct phfig *LV_phfig; + static struct obsTrack_s *LV_ttObs[LAYERS_NUMBER]; + static char LV_tLayersNames[LAYERS_NUMBER][LAYERS_ALIAS]; + static long LV_hTracksNumber; + static long LV_vTracksNumber; + static long LV_hTracksMax; + static long LV_vTracksMax; + static authtable *LV_htTerm; + + +/* ------------------------------------------------------------------ + * Internal functions. + */ + +# define SETMIN(v,m) ((v) = m_Min((v),(m))) +# define SETMAX(v,m) ((v) = m_Max((v),(m))) +# define LAMBDA2TRACKS(l) (lambda2pitch((l), F_PITCH_INF)) +# define TRACKS2LAMBDA(t) ((t) * TRACK_PITCH) +# define NORMVIASIDE(s) (((s) > MBK_VIA_SIDE) ? (s) : 0L) + + static void buildHTTerm __FP((struct phseg *apSeg)); + static void delHTTerm __FP((void)); + static long lambda2pitch __FP((long aLength, long aFlags)); + static long getLayerTable __FP((char aLayer)); + static void allocTableLayers __FP((void)); + static void allocTableObs __FP((void)); + static void addObs __FP((long aiTable, + long aX1, + long aY1, + long aX2, + long aY2)); + static void seg2obs __FP((struct phseg *apSeg)); + static void via2obs __FP((struct phvia *apVIA)); + static void instance2obs __FP((struct phins *pIns)); + extern void instances2obs __FP((void)); + static void wiring2obs __FP((void)); + static void obs2layers __FP((void)); + + +/* + * /----------------------------------------------------------------\ + * | Functions Definitions | + * \----------------------------------------------------------------/ + */ + +/* ------------------------------------------------------------------ + * Function : "buildHTTerm()". + */ + +static void buildHTTerm(apSeg) + struct phseg *apSeg; +{ + struct phseg *pSeg; + + + LV_htTerm = createauthtable (HT_TERM_SIZE); + + for (pSeg = apSeg; pSeg != NULL; pSeg = pSeg->NEXT) { + if (pSeg->NAME == NULL) { + eprinth ("rtu"); + eprintf ("\n Segment (%ld,%ld) (%ld,%ld) width %ld layer id %d", + pSeg->X1, + pSeg->Y1, + pSeg->X2, + pSeg->Y2, + pSeg->WIDTH, + (int)pSeg->LAYER); + eprintf ("\n doesn't have a name.\n"); + EXIT (1); + } + + if (!isCALU (pSeg->LAYER)) continue; + if (searchauthelem (LV_htTerm, pSeg->NAME)) continue; + + addauthelem (LV_htTerm, pSeg->NAME, 0); + } +} + + +/* ------------------------------------------------------------------ + * Function : "delHTTerm()". + */ + +static void delHTTerm() +{ + destroyauthtable (LV_htTerm); +} + + +/* ------------------------------------------------------------------ + * Function : "lambda2pitch()". + */ + +static long lambda2pitch(aLength, aFlags) + long aLength; + long aFlags; +{ + long pitch; + + + pitch = aLength / TRACK_PITCH; + + if (aFlags & F_PITCH_SUP) + pitch += (aLength % TRACK_PITCH) ? 1 : 0; + + return (pitch); +} + +/* ------------------------------------------------------------------ + * Function : "getLayerTable()". + */ + +static long getLayerTable(aLayer) + char aLayer; +{ + long iTable, iAlias; + + + for (iTable = 1; iTable < LAYERS_NUMBER; iTable++) { + for (iAlias = 0; iAlias < LAYERS_ALIAS; iAlias++) { + if (LV_tLayersNames[iTable][iAlias] == aLayer) { + return (iTable); + } + } + } + + /* No table found : return LAYERS_NUMBER. */ + return (LAYERS_NUMBER); +} + + +/* ------------------------------------------------------------------ + * Function : "allocTableLayers()". + */ + +static void allocTableLayers() +{ + /* Base layer. */ + LV_tLayersNames[0][0] = ALU1; + LV_tLayersNames[1][0] = ALU2; + LV_tLayersNames[2][0] = ALU3; + LV_tLayersNames[3][0] = ALU4; + LV_tLayersNames[4][0] = ALU5; + LV_tLayersNames[5][0] = ALU6; + + /* Associated obstacles layer. */ + LV_tLayersNames[0][1] = TALU1; + LV_tLayersNames[1][1] = TALU2; + LV_tLayersNames[2][1] = TALU3; + LV_tLayersNames[3][1] = TALU4; + LV_tLayersNames[4][1] = TALU5; + LV_tLayersNames[5][1] = TALU6; + + /* Associated terminal layer. */ + LV_tLayersNames[0][2] = CALU1; + LV_tLayersNames[1][2] = CALU2; + LV_tLayersNames[2][2] = CALU3; + LV_tLayersNames[3][2] = CALU4; + LV_tLayersNames[4][2] = CALU5; + LV_tLayersNames[5][2] = CALU6; +} + + +/* ------------------------------------------------------------------ + * Function : "allocTableObs()". + */ + +static void allocTableObs() +{ + long iTable, iTrack; + long tracksNumber, trackMax; + + + LV_hTracksNumber = LAMBDA2TRACKS (LV_phfig->YAB2 - LV_phfig->YAB1) + 1; + LV_hTracksMax = LAMBDA2TRACKS (LV_phfig->XAB2 - LV_phfig->XAB1) + 1; + + LV_vTracksNumber = LAMBDA2TRACKS (LV_phfig->XAB2 - LV_phfig->XAB1) + 1; + LV_vTracksMax = LAMBDA2TRACKS (LV_phfig->YAB2 - LV_phfig->YAB1) + 1; + + + for (iTable = 0; iTable < LAYERS_NUMBER; iTable++) { + if (!(iTable % 2)) { + /* i.e. ALU1, ALU3 & ALU5 : vertical tracks. */ + tracksNumber = LV_vTracksNumber; + trackMax = LV_vTracksMax; + } else { + /* i.e. ALU2, ALU4 & ALU6 : horizontal tracks. */ + tracksNumber = LV_hTracksNumber; + trackMax = LV_hTracksMax; + } + + + LV_ttObs[iTable] = (struct obsTrack_s*)mbkalloc ( + sizeof (struct obsTrack_s) * tracksNumber); + + /* Initialize table boundaries. */ + for (iTrack = 0; iTrack < tracksNumber; iTrack++) { + LV_ttObs[iTable][iTrack].min = trackMax; + LV_ttObs[iTable][iTrack].max = 0L; + } + } +} + + +/* ------------------------------------------------------------------ + * Function : "addObs()". + */ + +static void addObs(aiTable, aX1, aY1, aX2, aY2) + long aiTable; + long aX1, aY1, aX2, aY2; +{ + long iTrack, ivTrackMin, ivTrackMax; + long hTrackMin, hTrackMax; + + + if (!(aiTable % 2)) { + /* i.e. ALU1, ALU3 & ALU5 : vertical tracks. */ + hTrackMin = lambda2pitch (aY1 - LV_phfig->YAB1, F_PITCH_INF); + hTrackMax = lambda2pitch (aY2 - LV_phfig->YAB1, F_PITCH_SUP); + + ivTrackMin = lambda2pitch (aX1 - LV_phfig->XAB1, F_PITCH_INF); + ivTrackMax = lambda2pitch (aX2 - LV_phfig->XAB1, F_PITCH_SUP); + } else { + /* i.e. ALU2, ALU4 & ALU6 : horizontal tracks. */ + hTrackMin = lambda2pitch (aX1 - LV_phfig->XAB1, F_PITCH_INF); + hTrackMax = lambda2pitch (aX2 - LV_phfig->XAB1, F_PITCH_SUP); + + ivTrackMin = lambda2pitch (aY1 - LV_phfig->YAB1, F_PITCH_INF); + ivTrackMax = lambda2pitch (aY2 - LV_phfig->YAB1, F_PITCH_SUP); + } + + + for (iTrack = ivTrackMin; iTrack <= ivTrackMax; iTrack++) { + SETMIN (LV_ttObs[aiTable][iTrack].min, hTrackMin); + SETMAX (LV_ttObs[aiTable][iTrack].max, hTrackMax); + } +} + + +/* ------------------------------------------------------------------ + * Function : "seg2obs()". + */ + +static void seg2obs(apSeg) + struct phseg *apSeg; +{ + long iTable, X1, Y1, X2, Y2, trackWidth; + + + /* Special policy for xALU1 layers : segments are all passed "as is" + * in TALU1. + */ + switch (apSeg->LAYER) { + case ALU1: + case CALU1: + case TALU1: + /* Do nothing. + *addphseg (LV_phfig, + * TALU1, + * apSeg->WIDTH, + * apSeg->X1, + * apSeg->Y1, + * apSeg->X2, + * apSeg->Y2, + * STRING_OBSTACLE + * ); + */ + return; + } + + + iTable = getLayerTable (apSeg->LAYER); + + + if (iTable == LAYERS_NUMBER) return; + + + trackWidth = getLayerTrackWidth (apSeg->LAYER); + + switch (apSeg->TYPE) { + case UP: + case DOWN: + X1 = apSeg->X1 - (apSeg->WIDTH - trackWidth) / 2; + X2 = apSeg->X2 + (apSeg->WIDTH - trackWidth) / 2; + Y1 = apSeg->Y1; + Y2 = apSeg->Y2; + break; + case LEFT: + case RIGHT: + default: + X1 = apSeg->X1; + X2 = apSeg->X2; + Y1 = apSeg->Y1 - (apSeg->WIDTH - trackWidth) / 2; + Y2 = apSeg->Y2 + (apSeg->WIDTH - trackWidth) / 2; + break; + } + + addObs (iTable, X1, Y1, X2, Y2); +} + + +/* ------------------------------------------------------------------ + * Function : "via2obs()". + */ + +static void via2obs(apVIA) + struct phvia *apVIA; +{ + long iTable, X1, Y1, X2, Y2, trackWidth; + char layer; +# if 0 + char topLayer; +# endif + + + if (apVIA->NAME == NULL) { + eprinth ("rtu"); + eprintf ("\n VIA (%ld,%ld) size (%ld,%ld) type id %d", + MBKUNSCALE (apVIA->XVIA), + MBKUNSCALE (apVIA->YVIA), + MBKUNSCALE (apVIA->DX), + MBKUNSCALE (apVIA->DY), + (int)apVIA->TYPE); + eprintf ("\n doesn't have a name.\n"); + EXIT (1); + } + + + __DBG( fprintf (stderr, "via2obs(): VIA at %ld %ld.\n", + apVIA->XVIA, apVIA->YVIA); ) + + /* Check if this VIA belongs to an terminal net. */ + /* if (searchauthelem (LV_htTerm, apVIA->NAME)) return; */ + + + for (layer = getBottomVIALayer (apVIA->TYPE); TRUE; + layer = getUpVIALayer (apVIA->TYPE, layer)) { + iTable = getLayerTable (layer); + + if ((!isvdd (apVIA->NAME) && !isvss (apVIA->NAME)) || (iTable % 2)) { + if (iTable != LAYERS_NUMBER) { + __DBG (fprintf (stderr, " OBS Layer %d\n", (int)layer); ) + + trackWidth = getLayerTrackWidth (layer); + + X1 = apVIA->XVIA - (NORMVIASIDE(apVIA->DX) - trackWidth) / 2; + X2 = apVIA->XVIA + (NORMVIASIDE(apVIA->DX) - trackWidth) / 2; + Y1 = apVIA->YVIA - (NORMVIASIDE(apVIA->DY) - trackWidth) / 2; + Y2 = apVIA->YVIA + (NORMVIASIDE(apVIA->DY) - trackWidth) / 2; + + addObs (iTable, X1, Y1, X2, Y2); + } + } + + if (layer == getTopVIALayer (apVIA->TYPE)) break; + } + +# if 0 + fprintf (stderr, " Intermediate layers :\n"); + layer = getUpVIALayer (apVIA->TYPE, getBottomVIALayer (apVIA->TYPE)); + topLayer = getTopVIALayer (apVIA->TYPE); + + while (layer != topLayer) { + iTable = getLayerTable (layer); + + if (iTable != LAYERS_NUMBER) { + fprintf (stderr, " OBS Layer %d\n", (int)layer); + + trackWidth = getLayerTrackWidth (layer); + + X1 = apVIA->XVIA - (NORMVIASIDE(apVIA->DX) - trackWidth) / 2; + X2 = apVIA->XVIA + (NORMVIASIDE(apVIA->DX) - trackWidth) / 2; + Y1 = apVIA->YVIA - (NORMVIASIDE(apVIA->DY) - trackWidth) / 2; + Y2 = apVIA->YVIA + (NORMVIASIDE(apVIA->DY) - trackWidth) / 2; + + addObs (iTable, X1, Y1, X2, Y2); + } + + layer = getUpVIALayer (apVIA->TYPE, layer); + } +# endif +} + + +/* ------------------------------------------------------------------ + * Function : "instance2obs()". + */ + +static void instance2obs(apIns) + struct phins *apIns; +{ + struct phfig *pFig; + struct phseg *pSeg, flatSeg; +# if 0 + struct phvia *pVIA, flatVIA; + char *viaName = STRING_OBSTACLE; +# endif + + + pFig = getphfig (apIns->FIGNAME, 'A'); + + for (pSeg = pFig->PHSEG; pSeg != NULL; pSeg = pSeg->NEXT) { + if ( isvdd (pSeg->NAME ) || isvss (pSeg->NAME )) continue; + if (!isCALU (pSeg->LAYER) && !isobs (pSeg)) continue; + /*if (isCALU (pSeg->LAYER) || !isobs (pSeg)) continue;*/ + + xyflatseg (&flatSeg, pSeg, + apIns->XINS, apIns->YINS, + pFig->XAB1, pFig->YAB1, + pFig->XAB2, pFig->YAB2, + apIns->TRANSF); + + seg2obs (&flatSeg); + } + +# if 0 + for (pVIA = pFig->PHVIA; pVIA != NULL; pVIA = pVIA->NEXT) { + if (isvdd (pVIA->NAME) || isvss (pVIA->NAME)) continue; + + xyflatvia (&flatVIA, pVIA, + apIns->XINS, apIns->YINS, + pFig->XAB1, pFig->YAB1, + pFig->XAB2, pFig->YAB2, + apIns->TRANSF); + + flatVIA.NAME = (pVIA->NAME != NULL) ? pVIA->NAME : viaName; + + via2obs (&flatVIA); + } +# endif +} + + +/* ------------------------------------------------------------------ + * Function : "wiring2obs()". + */ + +static void wiring2obs() +{ + struct phseg *pSeg; + struct phvia *pVIA; + + + for (pSeg = LV_phfig->PHSEG; pSeg != NULL; pSeg = pSeg->NEXT) { + /* Terminals (i.e. segments in CALUx layers) are not to be + * considered as obstacles. + */ + /*if (!isCALU (pSeg->LAYER)) seg2obs (pSeg);*/ + if (!isvdd (pSeg->NAME) && !isvss (pSeg->NAME)) seg2obs (pSeg); + } + + for (pVIA = LV_phfig->PHVIA; pVIA != NULL; pVIA = pVIA->NEXT) { + /* Skip default VIA, as they belongs to regular wiring. */ + if (pVIA->DX || pVIA->DY) via2obs (pVIA); + } +} + + +/* ------------------------------------------------------------------ + * Function : "instances2obs()". + */ + +extern void instances2obs() +{ + struct phins *pIns; + + + for (pIns = LV_phfig->PHINS; pIns != NULL; pIns = pIns->NEXT) { + instance2obs (pIns); + } +} + + + +/* ------------------------------------------------------------------ + * Function : "obs2layers()". + */ + +static void obs2layers() +{ + long iTable, iTrack, tracksNumber; + long X1, Y1, X2, Y2, width; + char layer; + + + for (iTable = 0; iTable < LAYERS_NUMBER; iTable++) { + layer = getTALU (LV_tLayersNames[iTable][0]); + width = getLayerTrackWidth (layer); + + + if (!(iTable % 2)) { + /* i.e. ALU1, ALU3 & ALU5 : vertical tracks. */ + tracksNumber = LV_vTracksNumber; + } else { + /* i.e. ALU2, ALU4 & ALU6 : horizontal tracks. */ + tracksNumber = LV_hTracksNumber; + } + + + for (iTrack = 0; iTrack < tracksNumber; iTrack++) { + /* Skip empty tracks. */ + if (LV_ttObs[iTable][iTrack].min >= LV_ttObs[iTable][iTrack].max) + continue; + + if (!(iTable % 2)) { + /* i.e. ALU1, ALU3 & ALU5 : vertical tracks. */ + X1 = X2 = LV_phfig->XAB1 + TRACKS2LAMBDA (iTrack); + Y1 = LV_phfig->YAB1 + TRACKS2LAMBDA (LV_ttObs[iTable][iTrack].min); + Y2 = LV_phfig->YAB1 + TRACKS2LAMBDA (LV_ttObs[iTable][iTrack].max); + } else { + /* i.e. ALU2, ALU4 & ALU6 : horizontal tracks. */ + Y1 = Y2 = LV_phfig->YAB1 + TRACKS2LAMBDA (iTrack); + X1 = LV_phfig->XAB1 + TRACKS2LAMBDA (LV_ttObs[iTable][iTrack].min); + X2 = LV_phfig->XAB1 + TRACKS2LAMBDA (LV_ttObs[iTable][iTrack].max); + } + + + addphseg (LV_phfig, layer, width, X1, Y1, X2, Y2, STRING_OBSTACLE); + } /* End of "for (iTrack ...)". */ + } /* End of "for (iTable ...)". */ +} + + +/* ------------------------------------------------------------------ + * Function : "rtu()". + */ + +extern void rtu(aPhfig) + struct phfig *aPhfig; +{ + LV_phfig = aPhfig; + + + allocTableLayers (); + allocTableObs (); + + buildHTTerm (aPhfig->PHSEG); + instances2obs (); + wiring2obs (); + obs2layers (); + delHTTerm (); + +} diff --git a/alliance/src/sea/src/util_Sys.c b/alliance/src/sea/src/util_Sys.c new file mode 100644 index 00000000..785128de --- /dev/null +++ b/alliance/src/sea/src/util_Sys.c @@ -0,0 +1,520 @@ +/* + * $Id: util_Sys.c,v 1.1 2002/04/25 16:16:20 jpc Exp $ + * + * /----------------------------------------------------------------\ + * | | + * | A l l i a n c e C A D S y s t e m | + * | S i l i c o n E n s e m b l e / A l l i a n c e | + * | | + * | Author : Jean-Paul CHAPUT | + * | E-mail : alliance-support@asim.lip6.fr | + * | ============================================================== | + * | C Module : "./util_Sys.c" | + * | ************************************************************** | + * | U p d a t e s | + * | | + * \----------------------------------------------------------------/ + */ + + +# include "util_Defs.h" + + +/* ------------------------------------------------------------------ + * Global variables (declared `extern' in "util_Defs.h"). + */ + + long util_VL = 1L; + long util_flags = 0L; + char util_binName[1024] = "noname"; + + +/* ------------------------------------------------------------------ + * Internal functions declarations. + */ + + static void trapSig __FP((int aSig)); + + +/* + * /----------------------------------------------------------------\ + * | Functions Definitions | + * \----------------------------------------------------------------/ + */ + +/* ------------------------------------------------------------------ + * Function : "trapSig()". + */ + +static void trapSig(aSig) + int aSig; +{ + switch (aSig) + { + case C_SIGERR: + /* A "normal" error occurs (produced by 'esignal'). */ + break; + + case C_SIGTFLT: + /* "util_init" was unable to setup 'trapSig'. */ + eprinth ("util_Sys"); + eprints ("\n Unable to trap SOFTSIG|SIGSEGV|SIGTERM.\n"); + break; + + case SIGTERM: + /* This occurs on MBK errors. */ + eprinth ((char *)NULL); + eprints ("\n An error have occur in the MBK data-base."); + eprints ("\n Please check your Alliance environment."); + eprints ("\n\n"); + eprintf ("\n %s terminated.", util_binName); + eprints ("\n" ); + break; + + case SIGFPE: + case SIGBUS: + case SIGSEGV: + /* Ouch !! This may result from a program bug. */ + eprinth ((char *)NULL); + eprintf ("\n An %s internal bug have occur ", util_binName); + + if (aSig == SIGFPE ) eprints ("(SIGFPE)." ); + if (aSig == SIGBUS ) eprints ("(SIGBUS)." ); + if (aSig == SIGSEGV) eprints ("(SIGSEGV)."); + eprints ("\n Please e-mail to \"alliance-support@asim.lip6.fr\"."); + eprints ("\n\n"); + eprintf ("\n %s terminated ", util_binName); + + if (util_flags & F_NOCORE) { + eprints ("(core not dumped).\n"); + exit (1); + } + else { + eprints( "(core will be dumped).\n"); + if ( (signal(SIGFPE , SIG_DFL) == SIG_ERR) + || (signal(SIGBUS , SIG_DFL) == SIG_ERR) + || (signal(SIGSEGV, SIG_DFL) == SIG_ERR)) + exit (1); + else { + kill (getpid(), aSig); + return; + } + } + break; + + default: + /* Unexpected signal. */ + eprinth ("util_Sys"); + eprintf ("\n Unexpected signal \'%d\' in trap function.\n", aSig); + break; + } + + exit (1); +} + + +/* ------------------------------------------------------------------ + * Function : "trapInit()". + */ + +extern void trapInit() +{ + /* Set the trap function for the ERROR signal. */ + if (ssignal (C_SIGERR, trapSig) == SIG_ERR) { trapSig (C_SIGTFLT); } + + /* Set the trap function for SIGTERM signal. */ + if (signal(SIGTERM, trapSig) == SIG_ERR) { trapSig (C_SIGTFLT); } + + /* Set the trap function for SIGFPE, SIGBUS and SIGSEGV signals. */ + if ( (signal(SIGFPE , trapSig) == SIG_ERR) + || (signal(SIGBUS , trapSig) == SIG_ERR) + || (signal(SIGSEGV, trapSig) == SIG_ERR)) trapSig (C_SIGTFLT); +} + + +/* ------------------------------------------------------------------ + * Function : "sendGSignal()". + */ + +extern void sendGSignal(aSig) + int aSig; +{ + gsignal (aSig); +} + + +/* ------------------------------------------------------------------ + * Function : "setBinName()". + */ + +extern void setBinName (asName) + char *asName; +{ + strncpy (util_binName, asName, 1023); +} + + + +/* ------------------------------------------------------------------ + * Function : "stdflush()". + */ + +extern void stdflush() +{ + fflush(stdout); + fflush(stderr); +} + + +/* ------------------------------------------------------------------ + * Function : "errMBK()". + */ + +extern void errMBK(asName) + char *asName; +{ + stdflush(); + + fprintf(stderr, "\n*** MBK error ***:"); + + if (asName != (char *)NULL) { + fprintf(stderr, "%s:", asName); + } +} + + +/* ------------------------------------------------------------------ + * Function : "eprinth()". + */ + +extern void eprinth(asName) + char *asName; +{ + stdflush(); + + fprintf(stderr, "\n*** Error ***:"); + + if (asName != (char *)NULL) { + fprintf(stderr, "%s:", asName); + } +} + + +/* ------------------------------------------------------------------ + * Function : "eprintf()". + */ + +extern int eprintf __FPV((char *aFormat, ...)) +{ + va_list ArgList; + __KR_C( char *aFormat; ) + int retVal; + + + __ANSI_C( va_start(ArgList, aFormat); ) + __KR_C( va_start(ArgList); ) + __KR_C( aFormat = va_arg(ArgList, char*); ) + + retVal = vfprintf(stderr, aFormat, ArgList); + + va_end(ArgList); + + return(retVal); +} + + +/* ------------------------------------------------------------------ + * Function : "eprints()". + */ + +extern int eprints(aS) + char *aS; +{ + return(fputs(aS, stderr)); +} + + +/* ------------------------------------------------------------------ + * Function : "warnMBK()". + */ + +extern void warnMBK(asName) + char *asName; +{ + stdflush(); + + fprintf(stderr, "*** MBK warning ***:"); + + if (asName != (char *)NULL) { + fprintf(stderr, "%s:", asName); + } +} + + +/* ------------------------------------------------------------------ + * Function : "wprinth()". + */ + +extern void wprinth(asName) + char *asName; +{ + stdflush(); + + fprintf(stderr, "*** Warning ***:"); + + if (asName != (char *)NULL) { + fprintf(stderr, "%s:", asName); + } +} + + +/* ------------------------------------------------------------------ + * Function : "wprintf()". + */ + +extern int wprintf __FPV((char *aFormat, ...)) +{ + va_list AL; + __KR_C( char *aFormat; ) + int RV; + + __ANSI_C( va_start(AL, aFormat); ) + __KR_C( va_start(AL); ) + __KR_C( aFormat = va_arg(AL, char*); ) + + RV = vfprintf(stderr, aFormat, AL); + va_end(AL); + + return(RV); +} + + +/* ------------------------------------------------------------------ + * Function : "wprints()". + */ + +extern int wprints(aS) + char *aS; +{ + return(fputs(aS, stderr)); +} + + +/* ------------------------------------------------------------------ + * Function : "setVL()". + */ + +extern void setVL(aVL) + long aVL; +{ + switch (aVL) { + case C_VerboseLevel0: + case C_VerboseLevel1: + case C_VerboseLevel2: util_VL = aVL; break; + default: util_VL = C_VerboseLevel2; break; + } +} + + +/* ------------------------------------------------------------------ + * Function : "getVL()". + */ + +extern long getVL() +{ + return (util_VL); +} + + +/* ------------------------------------------------------------------ + * Function : "vmprintf()". + */ + +extern int vmprintf(aVL, aFormat, aArgList) + va_list aArgList; + long aVL; + char *aFormat; +{ + int retVal; + + + if (aVL <= util_VL) { + retVal = vfprintf (stdout, aFormat, aArgList); + } else { + retVal = 0; + } + + return (retVal); +} + + +/* ------------------------------------------------------------------ + * Function : "mprintf()". + */ + +extern int mprintf __FPV((long aVL, char *aFormat, ...)) +{ + va_list ArgList; + __KR_C( char aVL; ) + __KR_C( char *aFormat; ) + int retVal; + + + __ANSI_C( va_start (ArgList, aFormat); ) + __KR_C( va_start (ArgList); ) + __KR_C( aVL = va_arg (ArgList, long ); ) + __KR_C( aFormat = va_arg (ArgList, char*); ) + + retVal = vmprintf (aVL, aFormat, ArgList); + + va_end(ArgList); + + return(retVal); +} + + +/* ------------------------------------------------------------------ + * Function : "mprints()". + */ + +extern int mprints(aVL, aS) + long aVL; + char *aS; +{ + int retVal; + + + if (aVL <= util_VL) { + retVal = fputs (aS, stdout); + } else { + retVal = 0; + } + + return (retVal); +} + + +/* ------------------------------------------------------------------ + * Function : "mprintf0()". + */ + +extern int mprintf0 __FPV((char *aFormat, ...)) +{ + va_list ArgList; + __KR_C( char *aFormat; ) + int retVal; + + + __ANSI_C( va_start (ArgList, aFormat); ) + __KR_C( va_start (ArgList); ) + __KR_C( aFormat = va_arg (ArgList, char*); ) + + retVal = vmprintf (C_VerboseLevel0, aFormat, ArgList); + + va_end (ArgList); + + return (retVal); +} + + +/* ------------------------------------------------------------------ + * Function : "mprintf1()". + */ + +extern int mprintf1 __FPV((char *aFormat, ...)) +{ + va_list ArgList; + __KR_C( char *aFormat; ) + int retVal; + + + __ANSI_C( va_start (ArgList, aFormat); ) + __KR_C( va_start (ArgList); ) + __KR_C( aFormat = va_arg (ArgList, char*); ) + + retVal = vmprintf (C_VerboseLevel1, aFormat, ArgList); + + va_end (ArgList); + + return (retVal); +} + + +/* ------------------------------------------------------------------ + * Function : "mprintf2()". + */ + +extern int mprintf2 __FPV((char *aFormat, ...)) +{ + va_list ArgList; + __KR_C( char *aFormat; ) + int retVal; + + + __ANSI_C( va_start (ArgList, aFormat); ) + __KR_C( va_start (ArgList); ) + __KR_C( aFormat = va_arg (ArgList, char*); ) + + retVal = vmprintf (C_VerboseLevel2, aFormat, ArgList); + + va_end (ArgList); + + return (retVal); +} + + +/* ------------------------------------------------------------------ + * Function : "util_init()". + */ + +extern void util_init(aVL, aFlags, asName) + long aVL; + long aFlags; + char *asName; +{ + util_flags = aFlags; + + trapInit (); + setVL (aVL); + setBinName (asName); +} + + +/* ------------------------------------------------------------------ + * Function : "s64printf()". + */ + +extern char *s64printf __FPV((char *aFormat, ...)) +{ + va_list aAL; + __KR_C( char *aFormat; ) + + static char s64[64][SIZE_S64]; + static long iS = 0; + + + __ANSI_C( va_start(aAL, aFormat); ) + __KR_C( va_start(aAL); ) + __KR_C( aFormat = va_arg(aAL, char*); ) + + vsprintf(s64[(++iS) % 64] , aFormat, aAL); + + va_end(aAL); + + return(s64[iS % 64]); +} + + +/* ------------------------------------------------------------------ + * Function : "strtoup()". + */ + +extern char *strtoup (aS) + char *aS; +{ + char *p; + + for (p = aS; *p != '\0'; p++) *p = (char)toupper ((int)*p); + + return (aS); +}