static void drv_generic(FILE *ptfile, ptype_list *pttype) { struct logen *ptgen; if ( (pttype=getptype(pttype,LOGEN)) ) { fprintf (ptfile," generic (\n"); for (ptgen=pttype->DATA;ptgen;ptgen=ptgen->NEXT) { fprintf (ptfile," CONSTANT %s : ",ptgen->NAME); switch(ptgen->TYPE) { case GENTYPE_BIT: fputs("bit := ", ptfile); break; case GENTYPE_VAL: fputs("natural := ", ptfile); break; case GENTYPE_ARG: fputs("arg := ", ptfile); break; case GENTYPE_TEXT: fputs("string := ", ptfile); break; case GENTYPE_LIST: fputs("list := ", ptfile); break; } drv_genvalue(ptfile, ptgen); if (ptgen->NEXT) fputs(";\n",ptfile); } fputs("\n );\n",ptfile); } }
extern void improve_capa_critical_path(lofig_list* lofig, int optim_level) { ptype_list* ptype, *ptype2; loins_list* loins; locon_list* locon; chain_list *lofigchain; losig_list* losig; ptype_list* long_path; int change=1; /*relaxation algorithm*/ while (change) { change=0; long_path=critical_path(lofig); long_path=sort_capa(long_path); /* on all signals of the critical path, improve capa*/ for (ptype=long_path; ptype; ptype=ptype->NEXT) { losig=(losig_list*) ptype->DATA; if (!losig->NAMECHAIN) { fprintf(stderr,"improve_capa_critical_path: no name on signal\n"); autexit(1); } /*seek latest driver*/ ptype2=getptype(losig->USER,LOFIGCHAIN); if (!ptype2) { fprintf(stderr, "improve_capa_critical_path: no lofigchain on losig '%s'\n", (char*) losig->NAMECHAIN->DATA); autexit(1); } loins=NULL; for (lofigchain=ptype2->DATA; lofigchain; lofigchain=lofigchain->NEXT){ locon= (locon_list*) lofigchain->DATA; if (locon->DIRECTION==UNKNOWN) { fprintf(stderr,"BEH: 'linkage %s' isn't accepted\n", locon->NAME); autexit(1); } if (locon->TYPE==EXTERNAL || locon->DIRECTION==IN) continue; loins=locon->ROOT; if (loins_delay(loins,losig->NAMECHAIN->DATA)>ptype->TYPE) break; } /*instance has changed, re-evaluate critical path*/ if (loins && change_instance(loins, losig, lofig, optim_level)) { change=1; break; } } freeptype(long_path); } }
extern void final_eval_delay(befig_list *befig) { bereg_list *bereg; bebus_list *bebus; beout_list *beout; biabl_list *biabl; bepor_list* bepor; float delay; if (!befig) { fprintf(stderr,"eval_delay: NULL pointer\n"); exit(1); } /*constants*/ putdelay(getablatomone(),0); putdelay(getablatomzero(),0); for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) { /*only input*/ if (bepor->DIRECTION!=IN && bepor->DIRECTION!=INOUT && bepor->DIRECTION!=TRANSCV) continue; if (isvdd(bepor->NAME) || isvss(bepor->NAME)) continue; /* T + RC */ delay=getdelaylax(bepor->NAME) + getimpedancelax(bepor->NAME) * getcapacitance(bepor->NAME); putdelay(bepor->NAME,delay); } /*separ value from condition for flip-flop to avoid cycle*/ for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) { for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) { if (getptype(biabl->USER,ABL_STABLE)) { /*only flip-flop*/ search_abl(biabl->VALABL,befig); } } } for (beout=befig->BEOUT; beout; beout=beout->NEXT) { search_abl(beout->ABL,befig); /*do not define delay now*/ } for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) { for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) { search_abl(biabl->CNDABL,befig); search_abl(biabl->VALABL,befig); /*do not define delay now*/ } } }
static void search_name(char* name, befig_list* befig) { bereg_list* bereg; beaux_list* beaux; bebux_list* bebux; biabl_list* biabl; for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) { if (beaux->NAME!=name) continue; search_abl(beaux->ABL,befig); eval_delay(beaux->NAME,beaux->ABL); return; } for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) { if (bebux->NAME!=name) continue; for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) { search_abl(biabl->CNDABL,befig); search_abl(biabl->VALABL,befig); } eval_bus(bebux->NAME,bebux->BIABL); return; } for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) { if (bereg->NAME!=name) continue; for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) { search_abl(biabl->CNDABL,befig); /*only condition*/ if (!getptype(biabl->USER,ABL_STABLE)) { /*only latch*/ search_abl(biabl->VALABL,befig); } } /*calculate delay on clock setup for flip-flop and on all entries */ /*for latch*/ eval_reg(bereg->NAME,bereg->BIABL); return; } fprintf(stderr,"search_name: %s unknown\n",name); exit(1); }
extern void save_xsch(FILE* xsch_stream, lofig_list* lofig, ptype_list* long_path, int color_mode) { long color; ptype_list* ptype, *ptype2=NULL; float delay=0, delay_out=0; char mes[1024]; char* signame = NULL; locon_list* locon; losig_list* losig; float gradient=1; int count; loins_list* loins; char *source, *dest=NULL, *last_sig; chain_list* chain, *loinschain=NULL; chain_list* lofigchain; losig_list* losig_aux; /*build gradient*/ if (long_path && color_mode==XSCH_GRADIENT) { /*get time of last entry*/ count=1; for (ptype=long_path; ptype->NEXT; ptype=ptype->NEXT) count++; if (!ptype->DATA) { fprintf(stderr,"save_xsch: compute error\n"); exit(1); } delay=ptype->TYPE; gradient=delay/((float)XSCH_COLOR_MAX); } /*color for signals*/ for (losig=lofig->LOSIG; losig; losig=losig->NEXT) { if (!losig->NAMECHAIN || !losig->NAMECHAIN->DATA) { fprintf(stderr,"save_xsch: no name for signal\n"); exit(1); } signame=losig->NAMECHAIN->DATA; if (isvdd(signame) || isvss(signame)) continue; if (losig->TYPE==EXTERNAL) { /*search external output*/ ptype=getptype(losig->USER,LOFIGCHAIN); for (lofigchain=ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) { locon=lofigchain->DATA; if (locon->TYPE==EXTERNAL && locon->DIRECTION!=IN) break; } if (lofigchain) delay=getdelay(output_name(signame)); else delay=getdelay(signame); } else delay=getdelay(signame); switch (color_mode) { case XSCH_GRADIENT: color=gradient_color(delay,gradient); break; case XSCH_CRITICAL_PATH: default: color=XSCH_NEUTRAL_COLOR; break; } flush_losig(xsch_stream, signame, color, delay, losig->TYPE); } /*color for instances*/ for (loins=lofig->LOINS; loins; loins=loins->NEXT) { /*search signal output*/ for (locon=loins->LOCON; locon; locon=locon->NEXT) { if (locon->DIRECTION==UNKNOWN) { fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n", locon->NAME,loins->INSNAME); exit(1); } if (locon->DIRECTION==OUT || locon->DIRECTION==INOUT || locon->DIRECTION==TRISTATE || locon->DIRECTION==TRANSCV) break; } if (!locon) { fprintf(stderr,"save_xsch: no output found for '%s'\n",loins->INSNAME); exit(1); } losig=locon->SIG; signame=losig->NAMECHAIN->DATA; delay=getdelay(loins->INSNAME); switch (color_mode) { case XSCH_GRADIENT: color=gradient_color(delay,gradient); break; case XSCH_CRITICAL_PATH: default: /*is instance in critical path?*/ for (ptype=long_path; ptype; ptype=ptype->NEXT) { if ((char*)ptype->DATA!=signame) continue; /*if output and input signals belong to critical path, then instance belongs*/ for (locon=loins->LOCON; locon; locon=locon->NEXT) { if (locon->DIRECTION==OUT || locon->DIRECTION==TRISTATE) continue; losig_aux=locon->SIG; /*is signal in critical path?*/ for (ptype2=long_path; ptype2; ptype2=ptype2->NEXT) { if ((char*)ptype2->DATA==losig_aux->NAMECHAIN->DATA) break; } if (ptype2) break; } ptype=ptype2; /*found?*/ break; } /*build critical path list*/ if (ptype) loinschain=addchain(loinschain,loins); if (ptype) color=XSCH_RED_COLOR; else color=XSCH_NEUTRAL_COLOR; } flush_loins(xsch_stream, loins->INSNAME, color, delay); } /*color for connectors*/ for (locon=lofig->LOCON; locon; locon=locon->NEXT) { if (isvdd(locon->NAME) || isvss(locon->NAME)) continue; switch (locon->DIRECTION) { case IN: delay_out=getdelay(locon->NAME); sprintf(mes, "%d ps",(int)delay_out); break; case OUT: case TRISTATE: delay_out=getdelay(output_name(locon->NAME)); sprintf(mes, "%d ps",(int)delay_out); break; case INOUT: case TRANSCV: delay=getdelay(locon->NAME); delay_out=getdelay(output_name(locon->NAME)); sprintf(mes, "%d ps on input; %d ps on output",(int)delay,(int)delay_out); break; } switch (color_mode) { case XSCH_GRADIENT: color=gradient_color(delay_out,gradient); break; case XSCH_CRITICAL_PATH: default: /* seek if signal is in a long path*/ for (ptype=long_path; ptype; ptype=ptype->NEXT) { if ((char*)ptype->DATA==locon->NAME) break; } if (ptype) color=XSCH_RED_COLOR; else color=XSCH_NEUTRAL_COLOR; } flush_stream_special(xsch_stream, locon->NAME, color, mes); } /*critical path*/ if (loinschain && long_path && color_mode==XSCH_CRITICAL_PATH) { source=NULL; last_sig=NULL; for (ptype=long_path; ptype; ptype=ptype->NEXT) { signame=ptype->DATA; for (chain=loinschain; chain; chain=chain->NEXT) { loins=chain->DATA; /*search signal output*/ for (locon=loins->LOCON; locon; locon=locon->NEXT) { if (locon->DIRECTION==OUT || locon->DIRECTION==INOUT || locon->DIRECTION==TRISTATE || locon->DIRECTION==TRANSCV) { losig=locon->SIG; if (losig->NAMECHAIN->DATA==signame) { dest=loins->INSNAME; break; } } } if (locon) break; } /*if no instance found it is external connector. it has the same name than signal*/ if (!locon) dest=signame; if (source) flush_path(xsch_stream, source, last_sig, dest, XSCH_RED_COLOR, delay, INTERNAL); source=dest; last_sig=signame; } /*for last signal search output*/ if (losig) { ptype=getptype(losig->USER,LOFIGCHAIN); for (chain=ptype->DATA; chain; chain=chain->NEXT) { locon=chain->DATA; /*port of circuit*/ if (locon->TYPE==EXTERNAL) {dest=locon->NAME; break;} loins=locon->ROOT; /*register input if no error*/ if (locon->DIRECTION==IN || locon->DIRECTION==INOUT || locon->DIRECTION==TRANSCV) {dest=loins->INSNAME; break;} } flush_path(xsch_stream, source, signame, dest, XSCH_RED_COLOR, delay, losig->TYPE); } } freechain(loinschain); }
static ptype_list* search_long_path(loins_list* loins, befig_list* befig) { loins_list* loins_aux, *best_loins=NULL; locon_list* locon; losig_list* losig, *best_losig=NULL; char* signame; chain_list* loconchain; ptype_list* ptype, *ret; float max_delay=-1, delay; bereg_list* bereg; biabl_list* biabl; if (!loins) { fprintf(stderr,"search_long_path: NULL pointer\n"); exit(1); } /*seek the latest input in cell*/ for (locon=loins->LOCON; locon; locon=locon->NEXT) { /*only inputs*/ if (locon->DIRECTION==OUT || locon->DIRECTION==TRISTATE || isvss(locon->NAME) || isvdd(locon->NAME)) continue; losig=locon->SIG; if (!losig->NAMECHAIN) { fprintf(stderr,"search_long_path: NULL pointer\n"); exit(1); } signame=(char*) losig->NAMECHAIN->DATA; delay=getdelay(signame); if (delay>max_delay) { best_losig=losig; max_delay=delay; } } /*no input found -> constant*/ if (!best_losig) return NULL; losig=best_losig; ptype=getptype(losig->USER,LOFIGCHAIN); if (!ptype || !ptype->DATA) { fprintf(stderr,"search_long_path: NULL pointer\n"); exit(1); } signame=(char*) losig->NAMECHAIN->DATA; ret=addptype(NULL, (int) max_delay, signame); /*stop at leaves or flip-flop */ if (losig->TYPE==EXTERNAL) return ret; for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) { if (bereg->NAME!=signame) continue; /*is it a flip-flop?*/ for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) { if (getptype(biabl->USER,ABL_STABLE)) return ret; } } /*search driver of signal (latest if bus)*/ max_delay=-1; for (loconchain=(chain_list*) ptype->DATA; loconchain; loconchain=loconchain->NEXT) { locon=(locon_list*) loconchain->DATA; /*only outputs*/ if (locon->DIRECTION==IN || isvss(locon->NAME) || isvdd(locon->NAME) || locon->TYPE==EXTERNAL) continue; loins_aux=locon->ROOT; if (loins_aux==loins) continue; delay=getdelay(loins_aux->INSNAME); if (delay>max_delay) { best_loins=loins_aux; max_delay=delay; } } if (!best_loins) { fprintf(stderr,"search_long_path: no loins found for driving losig '%s'\n",signame); exit(1); } ret->NEXT=search_long_path(best_loins, befig); return ret; }
static ptype_list* search_long_path(losig_list* losig, int ck_include) { loins_list* best_loins=NULL; locon_list* locon; losig_list *best_losig=NULL; loins_list* loins; befig_list* befig; char* signame, *ck=NULL; int reg=0; /*flag for flip-flop*/ chain_list* lofigchain; ptype_list* ptype, *ret; double max_delay=-1, delay; cell_list* cell; biabl_list* biabl; if (!losig) { fprintf(stderr,"search_long_path: NULL pointer\n"); autexit(1); } if (!losig->NAMECHAIN) { fprintf(stderr,"search_long_path: no losig name\n"); autexit(1); } signame=(char*) losig->NAMECHAIN->DATA; /*control combinational loop, not to recurse infinitively*/ if ( searchauthelem( ControlLoop, (char*) losig ) ) { fprintf(stderr,"Warning: combinational loop on signal %s\n", signame ); return ret; } addauthelem( ControlLoop, (char*) losig, 1 ); /*search drivers*/ ptype=getptype(losig->USER,LOFIGCHAIN); if (!ptype || !ptype->DATA) { fprintf(stderr,"search_long_path: no lofigchain found\n"); autexit(1); } for (lofigchain=(chain_list*) ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) { locon=(locon_list*) lofigchain->DATA; if (locon->DIRECTION==UNKNOWN) { fprintf(stderr,"BEH: 'linkage %s' isn't accepted\n", locon->NAME); autexit(1); } /*only outputs*/ if (isvss(locon->NAME) || isvdd(locon->NAME) || locon->DIRECTION==IN || locon->TYPE==EXTERNAL) continue; loins=locon->ROOT; delay=loins_delay(loins,signame); if (delay>max_delay) { best_loins=loins; max_delay=delay; } } loins=best_loins; ret=addptype(NULL, (long) max_delay>=0?max_delay:getdelay(signame), losig); if (!loins) return ret; /*stop at flip-flop*/ cell=getCell(loins->FIGNAME); if (!cell) { fprintf(stderr,"library error: no cell '%s.vbe' found\n", loins->FIGNAME); autexit(1); } befig=cell->BEFIG; if (befig->BEREG) { for ( biabl = cell->BEFIG->BEREG->BIABL; biabl; biabl = biabl->NEXT ) { ptype=getptype(biabl->USER,ABL_STABLE); if (ptype) { /*do not include clock in path*/ if (!ck_include) return ret; reg=1; ck=ptype->DATA; break; } } } max_delay=-1; /*seek the latest input in cell*/ for (locon=loins->LOCON; locon; locon=locon->NEXT) { if (locon->DIRECTION==UNKNOWN) { fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n", locon->NAME,loins->FIGNAME); autexit(1); } /*only inputs*/ if (locon->DIRECTION==OUT || locon->DIRECTION==TRISTATE || isvss(locon->NAME) || isvdd(locon->NAME)) continue; /* if flip-flop, accept only clock */ if (reg && ck!=locon->NAME) continue; losig=locon->SIG; if (!losig->NAMECHAIN) { fprintf(stderr,"search_long_path: no name on signal\n"); autexit(1); } signame=(char*) losig->NAMECHAIN->DATA; delay=getdelay(signame); if (delay>max_delay) { best_losig=losig; max_delay=delay; } } losig=best_losig; /*no input found -> constant*/ if (!losig) return ret; ret->NEXT=search_long_path(losig,ck_include); return ret; }
static int insert_buffer(losig_list* losig, lofig_list* lofig, int optim_level, long index) { double capa, init_capa; cell_list* buffer; chain_list* namechain, *sigchain=NULL; char* signame; lofig_list* model; losig_list* losig_buf; loins_list* loins_buf; locon_list* locon; losig_list* losig_vdd=NULL, *losig_vss=NULL, *losig_aux; ptype_list* ptype, *buffer_ptype; double delay, best_delay, init_delay; loins_list* loins; chain_list* lofigchain,*newlofigchain=NULL; int buffer_is_better=0, change=1; /*flags*/ chain_list* pred; chain_list* temp; buffer=getCellbuffer(); /*no buffer in library*/ if (!buffer) return 0; if (!losig->NAMECHAIN) { fprintf(stderr,"insert_buffer: no name on signal\n"); autexit(1); } best_delay=critical_delay(lofig); init_capa=getcapacitance(losig->NAMECHAIN->DATA); /*add buffer to netlist*/ signame=getautoname(losig->NAMECHAIN->DATA); namechain=addchain(NULL,signame); losig_buf=addlosig(lofig,index,namechain,INTERNAL); putcapacitance(signame,0); putdelay(signame,0); model=getlofig(buffer->BEFIG->NAME,'A'); /*search vdd and vss*/ for (locon=lofig->LOCON; locon; locon=locon->NEXT) { if (isvdd(locon->NAME)) losig_vdd=locon->SIG; if (isvss(locon->NAME)) losig_vss=locon->SIG; } /*build list of signal*/ for (locon=model->LOCON;locon; locon=locon->NEXT) { if (locon->DIRECTION==UNKNOWN) { fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n", locon->NAME,model->NAME); autexit(1); } if (isvdd(locon->NAME)) losig_aux=losig_vdd; else if (isvss(locon->NAME)) losig_aux=losig_vss; else if (locon->DIRECTION==OUT) losig_aux=losig_buf; else if (locon->DIRECTION==IN) losig_aux=losig; else { fprintf(stderr,"insert_buffer: buffer port '%s' unknown\n",locon->NAME); autexit(1); } sigchain=addchain(sigchain,losig_aux); } sigchain=reverse(sigchain); loins_buf=addloins(lofig,signame,model,sigchain); freechain(sigchain); /*to check changes*/ init_delay=getdelay(losig->NAMECHAIN->DATA); init_capa=getcapacitance(losig->NAMECHAIN->DATA); loins_capacitance(loins_buf,1/*add capa*/); /*lofigchain*/ for (locon=loins_buf->LOCON;locon; locon=locon->NEXT) { if (locon->DIRECTION==UNKNOWN) { fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n", locon->NAME,loins_buf->INSNAME); autexit(1); } if (isvdd(locon->NAME)) losig_aux=losig_vdd; else if (isvss(locon->NAME)) losig_aux=losig_vss; else if (locon->DIRECTION==OUT) losig_aux=losig_buf; else if (locon->DIRECTION==IN) losig_aux=losig; else { fprintf(stderr,"insert_buffer: buffer port '%s' unknown\n",locon->NAME); autexit(1); } ptype=getptype(losig_aux->USER,LOFIGCHAIN); if (!ptype) losig_aux->USER=addptype(losig_aux->USER,LOFIGCHAIN,addchain(NULL,locon)); else ptype->DATA=addchain(ptype->DATA,locon); } /*move all instance after buffer*/ ptype=getptype(losig->USER,LOFIGCHAIN); buffer_ptype=getptype(losig_buf->USER,LOFIGCHAIN); if (!ptype || !buffer_ptype) { fprintf(stderr,"insert_buffer: LOFIGCHAIN not found\n"); autexit(1); } for (lofigchain=((chain_list*)ptype->DATA)->NEXT/*first is entry of buffer*/; lofigchain; lofigchain=lofigchain->NEXT) { locon=(locon_list*) lofigchain->DATA; if (locon->DIRECTION==UNKNOWN) { fprintf(stderr,"BEH: 'linkage %s' isn't accepted\n", locon->NAME); autexit(1); } /*do not move drivers and port of circuit*/ if (locon->TYPE==EXTERNAL || locon->DIRECTION!=IN) { newlofigchain=addchain(newlofigchain,locon); continue; } loins=locon->ROOT; /*change capacitance*/ loins_capacitance(loins,0/*remove capa*/); /*change netlist*/ locon->SIG=losig_buf; buffer_ptype->DATA=addchain(buffer_ptype->DATA,locon); loins_capacitance(loins,1/*add capa*/); } /*put back drivers*/ freechain(((chain_list*)ptype->DATA)->NEXT/*first is entry of buffer*/); ((chain_list*)ptype->DATA)->NEXT=newlofigchain; /*eval all changes*/ propagate_loins_delay(loins_buf); /*relaxation algorithm*/ while (change) { change=0; pred=NULL; buffer_ptype=getptype(losig_buf->USER,LOFIGCHAIN); ptype=getptype(losig->USER,LOFIGCHAIN); if (!buffer_ptype || !buffer_ptype->DATA) { fprintf(stderr,"insert_buffer: LOFIGCHAIN is empty\n"); autexit(1); } /*put critical path before buffer*/ for (lofigchain=buffer_ptype->DATA; lofigchain->NEXT/*last is buffer output*/; lofigchain=lofigchain->NEXT) { locon=lofigchain->DATA; loins=locon->ROOT; /*change capacitance*/ loins_capacitance(loins,0/*remove capa*/); /*change netlist*/ locon->SIG=losig; ptype->DATA=addchain(ptype->DATA,locon); loins_capacitance(loins,1/*add capa*/); /*put over*/ if (pred) pred->NEXT=lofigchain->NEXT; else buffer_ptype->DATA=lofigchain->NEXT; /*eval all changes*/ propagate_loins_delay(loins); propagate_loins_delay(loins_buf); delay=critical_delay(lofig); if (delay<best_delay) { /*finish change*/ best_delay=delay; change=1; /*flag of change*/ buffer_is_better=1; lofigchain->NEXT=NULL; freechain(lofigchain); break; } else { /*remove change*/ if (pred) pred->NEXT=lofigchain; else buffer_ptype->DATA=lofigchain; /*unchange capacitance*/ loins_capacitance(loins,0/*remove capa*/); /*unchange netlist*/ locon->SIG=losig_buf; temp=ptype->DATA; ptype->DATA=temp->NEXT; temp->NEXT=NULL; freechain(temp); loins_capacitance(loins,1/*add capa*/); /*avoid change*/ propagate_loins_delay(loins_buf); propagate_loins_delay(loins); /*for next loop*/ pred=lofigchain; } } }/*end of while*/ if (buffer_is_better) { /*chose the best buffer*/ change_instance(loins_buf, losig_buf, lofig, optim_level); } else { /*if insert buffer is worst than before, remove it*/ /*remove all references of buffer in lofigchain*/ for (locon=loins_buf->LOCON; locon; locon=locon->NEXT) { losig_aux=locon->SIG; ptype=getptype(losig_aux->USER,LOFIGCHAIN); if (!ptype) break; pred=NULL; for (lofigchain=ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) { if (lofigchain->DATA==locon) { if (pred) pred->NEXT=lofigchain->NEXT; else ptype->DATA=lofigchain->NEXT; lofigchain->NEXT=NULL; freechain(lofigchain); break; } pred=lofigchain; } } buffer_ptype=getptype(losig_buf->USER,LOFIGCHAIN); ptype=getptype(losig->USER,LOFIGCHAIN); if (buffer_ptype) { for (lofigchain=buffer_ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) { locon=lofigchain->DATA; loins=locon->ROOT; /*change capacitance*/ loins_capacitance(loins,0/*remove capa*/); /*change netlist*/ locon->SIG=losig; ptype->DATA=addchain(ptype->DATA,locon); loins_capacitance(loins,1/*add capa*/); propagate_loins_delay(loins); } freechain(buffer_ptype->DATA); buffer_ptype->DATA=NULL; } loins_capacitance(loins_buf,0/*remove capa*/); dellosig(lofig,index); delloins(lofig,loins_buf->INSNAME); propagate_losig_delay(losig); /*verify no change on timing*/ delay=critical_delay(lofig); capa=getcapacitance(losig->NAMECHAIN->DATA); //01/09/2004 xtof's modification: rounding problem if ((int)(capa + 0.5)!=(int)(init_capa + 0.5) || (int)(delay + 0.5)!=(int)(best_delay + 0.5) || (int)(init_delay + 0.5)!=(int)(getdelay(losig->NAMECHAIN->DATA) + 0.5)) { fprintf(stderr, "insert_buffer: compute error %e!=%e fF %f!=%f ps %f!=%f ps\n", capa,init_capa,delay,best_delay, init_delay, getdelay(losig->NAMECHAIN->DATA)); autexit(1); } } return buffer_is_better; }