/* * This file is part of the Alliance CAD System * Copyright (C) Laboratoire LIP6 - Département ASIM * Universite Pierre et Marie Curie * * Home page : http://www-asim.lip6.fr/alliance/ * E-mail : mailto:alliance-users@asim.lip6.fr * * This progam is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * Alliance VLSI CAD System is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along * with the GNU C Library; see the file COPYING. If not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Tool : BooG - read all cells * Date : 2000 * Author : Francois Donnet */ #include #include #include #include #include #include #include #include #include #include "bog_normalize_register.h" #include "bog_normalize_ARITY.h" #include "bog_normalize_DAG.h" #include "bog_normalize_simplify.h" #include "bog_normalize_power.h" #include "bog_lib_utils.h" #include "bog_lib_cell.h" #include "bog_lib_negativ.h" #include "bog_lib_format.h" #include "bog_lib_permute.h" #include "bog_lib_specifications.h" #include "bog_lib_matching.h" #include "bog_map_pattern.h" #include "bog_lib_reader.h" /***************************************************************************/ /* return a list of files in directory path with the extension ext */ /* if error in path then return NULL */ /***************************************************************************/ extern chain_list *getfiles_with_ext (char *path, char *ext) { DIR *dir; struct dirent *entry; char *filename; char *completefilename; int filenamelength, extensionlength, pathlength; chain_list *head; if (!path || !ext) return NULL; dir = opendir (path); if (!dir) return NULL; extensionlength = strlen (ext); pathlength = strlen (path); head=NULL; while ((entry = readdir (dir)) != NULL) { filename = entry->d_name; filenamelength = strlen (filename); if (filenamelength <= extensionlength) continue; /* is extension of filename accepted */ if (strncmp (filename + filenamelength - extensionlength, ext, extensionlength)) continue; completefilename = mbkalloc(filenamelength + 1); sprintf(completefilename, "%s", filename); head = addchain (head, completefilename); } return head; } /******************************************************************************/ /* for each aspect of abl, build a cell */ /* return 1 if included in library */ /******************************************************************************/ static int distribCell(befig_list* befig) { chain_list *permutations=NULL; chain_list *chain; cell_list *cells_lib, *cell, *pred; char *old_cell; biabl_list *biabl_befig, *biabl_cell, *biabl; /*register*/ if (befig->BEREG) { for (biabl_befig=befig->BEREG->BIABL; biabl_befig; biabl_befig=biabl_befig->NEXT) { if ( internal_reference(befig,NULL,biabl_befig->VALABL) ) return 0; if ( internal_reference(befig,NULL,biabl_befig->CNDABL) ) return 0; /*in negativ logic, propagate NOT*/ biabl_befig->CNDABL=inv_oper(biabl_befig->CNDABL,0); biabl_befig->VALABL=inv_oper(biabl_befig->VALABL,0); /*minmize number of NOT*/ biabl_befig->CNDABL=build_negativ(biabl_befig->CNDABL); biabl_befig->VALABL=build_negativ(biabl_befig->VALABL); } cells_lib=getcell_register_lib(); /*check the use of inserting this cell*/ for (cell=cells_lib; cell; cell=cell->NEXT) { /*new match a cell description?*/ biabl_befig=befig->BEREG->BIABL; for (biabl_cell=cell->BIABL; biabl_cell; biabl_cell=biabl_cell->NEXT) { if (!biabl_befig || !pattern_matching(biabl_befig->CNDABL,biabl_cell->CNDABL) || !pattern_matching(biabl_befig->VALABL,biabl_cell->VALABL)) break; biabl_befig=biabl_befig->NEXT; } /*not the good cell to compare*/ if (biabl_cell) continue; /* patterns are equal? */ biabl_cell=cell->BIABL; for (biabl_befig=befig->BEREG->BIABL; biabl_befig; biabl_befig=biabl_befig->NEXT) { if (!biabl_cell || !pattern_matching(biabl_cell->CNDABL,biabl_befig->CNDABL) || !pattern_matching(biabl_cell->VALABL,biabl_befig->VALABL)) break; biabl_cell=biabl_cell->NEXT; } /*patterns aren't equal, new is more precise*/ if (!biabl_befig) break; /*patterns are equal -->comparison*/ if (cell->AREAAREA==getgenericarea(befig)) break; /*insert new*/ /*remove old cells because they are bigger*/ #if 0 fprintf(stderr,"Mapping Warning: a smaller cell than '%s' exists\n",cell->NAME); #endif old_cell=cell->NAME; pred=NULL; for (cell=cells_lib ; cell; cell=cell->NEXT) { if (cell->NAME==old_cell && pred) pred->NEXT=cell->NEXT; else if (cell->NAME==old_cell) cells_lib=cell->NEXT; else pred=cell; } setcell_register_lib(cells_lib); break; /*insert new*/ } /*give the list of different permutations*/ permutations=different_biabl(befig,befig->BEREG->BIABL); /*put in cell*/ for (chain=permutations; chain; chain=chain->NEXT) { biabl= (biabl_list*) chain->DATA; addCell_register(befig, biabl); } } /*bus*/ else if (befig->BEBUS) { for (biabl_befig=befig->BEBUS->BIABL; biabl_befig; biabl_befig=biabl_befig->NEXT) { /*in negativ logic, propagate NOT*/ biabl_befig->CNDABL=inv_oper(biabl_befig->CNDABL,0); biabl_befig->VALABL=inv_oper(biabl_befig->VALABL,0); /*minmize number of NOT*/ biabl_befig->CNDABL=build_negativ(biabl_befig->CNDABL); biabl_befig->VALABL=build_negativ(biabl_befig->VALABL); } cells_lib=getcell_tristate_lib(); /*check the use of inserting this cell*/ for (cell=cells_lib; cell; cell=cell->NEXT) { /*new match a cell description?*/ biabl_befig=befig->BEBUS->BIABL; for (biabl_cell=cell->BIABL; biabl_cell; biabl_cell=biabl_cell->NEXT) { if (!biabl_befig || !pattern_matching(biabl_befig->CNDABL,biabl_cell->CNDABL) || !pattern_matching(biabl_befig->VALABL,biabl_cell->VALABL)) break; biabl_befig=biabl_befig->NEXT; } /*not the good cell to compare*/ if (biabl_cell) continue; /* patterns are equal? */ biabl_cell=cell->BIABL; for (biabl_befig=befig->BEBUS->BIABL; biabl_befig; biabl_befig=biabl_befig->NEXT) { if (!biabl_cell || !pattern_matching(biabl_cell->CNDABL,biabl_befig->CNDABL) || !pattern_matching(biabl_cell->VALABL,biabl_befig->VALABL)) break; biabl_cell=biabl_cell->NEXT; } /*patterns aren't equal, new is more precise*/ if (!biabl_befig) break; /*patterns are equal -->comparison*/ if (cell->AREAAREA==getgenericarea(befig)) break; /*insert new*/ /*remove old cells because they are bigger*/ #if 0 fprintf(stderr,"Mapping Warning: a smaller cell than '%s' exists\n",cell->NAME); #endif old_cell=cell->NAME; pred=NULL; for (cell=cells_lib ; cell; cell=cell->NEXT) { if (cell->NAME==old_cell && pred) pred->NEXT=cell->NEXT; else if (cell->NAME==old_cell) cells_lib=cell->NEXT; else pred=cell; } setcell_tristate_lib(cells_lib); break; /*insert new*/ } /*give the list of different permutations*/ permutations=different_biabl(befig,befig->BEBUS->BIABL); /*put in cell*/ for (chain=permutations; chain; chain=chain->NEXT) { biabl= (biabl_list*) chain->DATA; addCell_bus(befig, biabl); } } /*logic*/ else if (befig->BEOUT) {/*pure logical*/ /*in negativ logic, propagate NOT*/ befig->BEOUT->ABL=inv_oper(befig->BEOUT->ABL,0); /*minmize number of NOT*/ befig->BEOUT->ABL=build_negativ(befig->BEOUT->ABL); cells_lib=getcell_logic_lib(); /*check the use to insert this cell*/ for (cell=cells_lib; cell; cell=cell->NEXT) { /*new more precise than old -> put new before*/ if (pattern_matching(befig->BEOUT->ABL,cell->ABL)) { /*patterns are equal*/ if (pattern_matching(cell->ABL,befig->BEOUT->ABL)) { if (cell->AREAAREA==getgenericarea(befig)) break; /*insert new*/ /*remove old cells because they are bigger*/ #if 0 fprintf(stderr,"Mapping Warning: a smaller cell than '%s' exists\n",cell->NAME); #endif old_cell=cell->NAME; pred=NULL; for (cell=cells_lib ; cell; cell=cell->NEXT) { if (cell->NAME==old_cell && pred) pred->NEXT=cell->NEXT; else if (cell->NAME==old_cell) cells_lib=cell->NEXT; else pred=cell; } setcell_logic_lib(cells_lib); } /*insert new*/ break; } } /*give the list of different permutations*/ permutations=different_abl(befig,befig->BEOUT->ABL); for (chain=permutations; chain; chain=chain->NEXT) { /*several abl for a same behavior!!! ex: and(or ...) == nor(nor...)*/ addCell_logic(befig, chain->DATA); } } if (permutations) freechain(permutations); return 1; } /*****************************************************************************/ /* build the cell library */ /*****************************************************************************/ extern void library_reader(char* cell_directory) { char *name; chain_list* vbe_list, *chain; befig_list* befig; char* memo_work; char** memo_cata; char* new_cata[2]; if (!cell_directory) { fprintf(stderr,"library_reader: no Cell directory\n"); exit(1); } /*seek vbe files which describe the lib*/ vbe_list=getfiles_with_ext (cell_directory, ".vbe"); /*search only in our library not to interfer with others*/ memo_work=WORK_LIB; memo_cata=CATA_LIB; WORK_LIB=cell_directory; CATA_LIB=new_cata; new_cata[0]=cell_directory; new_cata[1]=NULL; if (!vbe_list /*list of name*/) { fprintf(stderr, "Library Error: no cell in directory '%s'\n", cell_directory?cell_directory:"."); exit(1); } for (chain=vbe_list; chain; chain=chain->NEXT) { /*put off extension*/ name=chain->DATA; name[strlen(name)-strlen(".vbe")]='\0'; /* mode: BVL_KEEPAUX , BVL_TRACE ... */ /*do not keep aux*/ befig=vhdlloadbefig(NULL,name,'P'); if (befig->ERRFLG) { fprintf(stderr, "BEH: unknown error %d in %s.vbe\n",befig->ERRFLG,name); fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",name); continue; } /*detect power and forbid Vdd and Vss in expression*/ if (!detect_power(befig)) { fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",befig->NAME); continue; } /*simplify abl expression -needed by format_register()- */ simplify_expr(befig); /*remove stable -needed by DAG_control()- */ if (!format_register(befig)) { fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",befig->NAME); continue; } /*control cycles in befig and erase unused bebux and beaux*/ if (!DAG_control(befig)) { fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",befig->NAME); continue; } /*if constraints are respected*/ if (!format_cell(befig)) { fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",befig->NAME); continue; } /*put the locon of lofig in the same order than bepor of befig*/ if (sortbepor(befig)) { fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",befig->NAME); continue; } /*put arity oper*/ put_arity(befig); /*memorize cell if not already exists*/ if (!distribCell(befig)) { fprintf(stderr,"Mapping Warning: Cell '%s' isn't supported\n",befig->NAME); } } freechain(vbe_list); /*relax old env*/ WORK_LIB=memo_work; CATA_LIB=memo_cata; }