Ejemplo n.º 1
0
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);
   }

}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
static int change_instance(loins_list* loins, losig_list* losig, lofig_list* lofig, int optim_level)
{
   losig_list* losig_aux;
   lofig_list* lofig_aux;
   double critical, best_critical, delay, best_delay;
   double RC_max, T_max;
   locon_list* locon, *locon_aux;
   int change=0;
   cell_list* cell, *best;

   best=getCell(loins->FIGNAME);
   if (!best || best->NAME!=loins->FIGNAME) {
      fprintf(stderr,"library error: no cell '%s.vbe' found\n",loins->FIGNAME);
      autexit(1);
   }
  
   if (!losig->NAMECHAIN) {
      fprintf(stderr,"change_instance: no name on signal\n");
      autexit(1);
   }

   best_critical=critical_delay(lofig);
   best_delay=loins_delay(loins,losig->NAMECHAIN->DATA);
   /*compare RC and delay of instance*/
   RC_max=loins_max_RC(loins,losig->NAMECHAIN->DATA);
   T_max=loins_max_T(loins);
   
   /*check all cell of the same kind*/
   for (cell=sameCells(loins->FIGNAME); cell; cell=cell->NEXT) {
      /*eval critical*/
      loins_capacitance(loins,0);  /*remove own capacity*/
      loins->FIGNAME=cell->NAME;   /*change cell*/
      loins_capacitance(loins,1); /*add its own capacity (cell has changed)*/
      propagate_loins_delay(loins);
      critical=critical_delay(lofig);
      delay=loins_delay(loins,losig->NAMECHAIN->DATA);
     
      /*take new solution?*/
      if ( 
      (critical<best_critical && (cell->AREA<=best->AREA || optim_level>OPTIM_DELAY0))
      || (critical==best_critical && delay<best_delay && (cell->AREA<=best->AREA || optim_level>=OPTIM_DELAY4 || (RC_max>T_max && optim_level>=OPTIM_DELAY1))) 
      || (critical==best_critical && delay==best_delay && cell->AREA<best->AREA)
      ) {
         best_critical=critical;
         best=cell;
         best_delay=delay;
         change=1;
      }
      
   }  /*end of loop on cell*/
   
   loins_capacitance(loins,0);  /*substract own capacity*/
   loins->FIGNAME=best->NAME;
  
   /*capacitance and critical delay*/
   loins_capacitance(loins,1); /*add it own capacity (cell has changed)*/
   propagate_loins_delay(loins);
   
   /*verify change of loins*/
   critical=critical_delay(lofig);
   delay=loins_delay(loins,losig->NAMECHAIN->DATA);
   if ((int)critical!=(int)best_critical || (int)delay!=(int)best_delay) {
      fprintf(stderr,
      "change_instance: compute error %f!=%f ps   %f!=%f ps    (%sdue to caller)\n",
      critical,best_critical,delay,best_delay,change?"not ":"");
      autexit(1);
   }  
   
   
   
   /*if cell doesn't exist but is composed by several cells*/
   /*map port with real order*/
   if (best->MODE=='A' || best->MODE=='a') {
      loins_capacitance(loins,0);  /*substract own capacity*/
      /*change names*/
      loins->FIGNAME=best->BEFIG->NAME;
      lofig_aux=getlofig(best->NAME,'A');
      for (locon=loins->LOCON; locon; locon=locon->NEXT) {
         /*search locon in model*/
         for (locon_aux=lofig_aux->LOCON; locon_aux; locon_aux=locon_aux->NEXT){
            if (locon->NAME==locon_aux->NAME) break;
         }        
         if (!locon_aux) {
            fprintf(stderr,"change_instance: locon '%s' not found\n",
            locon->NAME);
            autexit(1);
         }
         losig_aux=locon_aux->SIG;
         /*search real connection*/
         for (locon_aux=lofig_aux->LOINS->LOCON; locon_aux; 
           locon_aux=locon_aux->NEXT){
            if (losig_aux==locon_aux->SIG) break;
         }        
         if (!locon_aux) {
            fprintf(stderr,"change_instance: locon '%s' not found in cell\n",
            locon->NAME);
            autexit(1);
         }
         locon->NAME=locon_aux->NAME;
      }
     
      /*capacitance and critical delay*/
      loins_capacitance(loins,1); /*add it own capacity (cell has changed)*/
      propagate_loins_delay(loins);
      
      /*verify change of loins*/
      critical=critical_delay(lofig);
      delay=loins_delay(loins,losig->NAMECHAIN->DATA);
      if ((int)critical!=(int)best_critical || (int)delay!=(int)best_delay) {
         fprintf(stderr,
         "change_instance: flatten error %f!=%f ps   %f!=%f ps\n",
         critical,best_critical,delay,best_delay);
         autexit(1);
      }   
   
   }  /*end of change loins*/

   
   return change;
}