static void find_d_z_abl(chain_list* abl, long value) { if (ABL_ATOM(abl)) { if (ABL_ATOM_VALUE(abl)==getablatomdc()/* = namealloc("'d'")*/) { /*non standard IEEE VHDL*/ /*it means "don't care"*/ /* we can put zero either one, only to simplify*/ ABL_CAR_L(abl)=value?getablatomone():getablatomzero(); } else if (ABL_ATOM_VALUE(abl)==getablatomtristate()/* =namealloc("'z'")*/){ /*no drive on signal*/ /* a pull-up is done for better conductance*/ ABL_CAR_L(abl)=getablatomone()/* = namealloc("'1'")*/; } return; } /*the first operator influences the most*/ switch (ABL_OPER(abl)) { case ABL_OR: case ABL_NOR: value=1; case ABL_AND: case ABL_NAND: value=0; } /*for each operator*/ for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) { find_d_z_abl(ABL_CAR(abl),value); } }
static int loc_pattern_matching(chain_list* expr, chain_list* pattern) { if (!expr || !pattern) { fprintf(stderr,"loc_pattern_matching: NULL pointer\n"); exit(1); } /*pattern is an atom*/ if (ABL_ATOM (pattern)) { /*constants MUST match*/ if (ABL_ATOM_VALUE(pattern)==getablatomone()) { if (ABL_ATOM(expr) && ABL_ATOM_VALUE(expr)==getablatomone()) return 1; else return 0; } if (ABL_ATOM_VALUE(pattern)==getablatomzero()) { if (ABL_ATOM(expr) && ABL_ATOM_VALUE(expr)==getablatomzero()) return 1; else return 0; } if (ABL_ATOM_VALUE(pattern)==getablatomdc() /* 'd' */) { if (ABL_ATOM(expr) && ABL_ATOM_VALUE(expr)==getablatomdc()) return 1; else return 0; } if (ABL_ATOM_VALUE(pattern)==getablatomtristate() /* 'z' */) { if (ABL_ATOM(expr) && ABL_ATOM_VALUE(expr)==getablatomtristate()) return 1; else return 0; } return relation_between(expr,ABL_ATOM_VALUE(pattern)); } /* pattern isn't an atom and expr is*/ if (ABL_ATOM (expr)) return 0; /* not the same oper */ if (ABL_OPER (expr) != ABL_OPER (pattern)) return 0; if (ABL_ARITY (expr) != ABL_ARITY (pattern)) return 0; for (pattern = ABL_CDR(pattern); pattern&&expr; pattern=ABL_CDR(pattern)) { expr = ABL_CDR(expr); if (!expr) return 0; if (!loc_pattern_matching(ABL_CAR (expr), ABL_CAR (pattern))) return 0; } return 1; }
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*/ } } }
extern void adapt_for_cell(befig_list *befig) { beout_list* beout; bebus_list* bebus; bereg_list* bereg; bebux_list* bebux; beaux_list* beaux; biabl_list* biabl; bepor_list* bepor; char* name; /*constants*/ putcapacitance(getablatomone(),0); putcapacitance(getablatomzero(),0); /*init*/ for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) { name=getoppositename(beaux->NAME); putcapacitance(beaux->NAME,0); putcapacitance(name,0); } for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) { name=getoppositename(bereg->NAME); putcapacitance(bereg->NAME,0); putcapacitance(name,0); } for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) { name=getoppositename(bebux->NAME); putcapacitance(bebux->NAME,0); putcapacitance(name,0); } for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) { /*inputs only*/ if (isvss(bepor->NAME) || isvdd(bepor->NAME)) continue; switch (bepor->DIRECTION) {case OUT: case TRISTATE: continue;} name=getoppositename(bepor->NAME); putcapacitance(bepor->NAME,0); putcapacitance(name,0); } /*adapt abl for cell of library and eval capacitance*/ for (beout=befig->BEOUT; beout; beout=beout->NEXT) { beout->ABL=inv_oper(beout->ABL,0); /*propagate NOT*/ beout->ABL=build_negativ(beout->ABL); /*minimize inverters*/ /*adapt the abl to match with a big cell later*/ beout->ABL=adapt_abl(beout->ABL); /*count capacitance of leaves*/ } for (beaux=befig->BEAUX; beaux; beaux=beaux->NEXT) { beaux->ABL=inv_oper(beaux->ABL,0); /*propagate NOT*/ beaux->ABL=build_negativ(beaux->ABL); /*minmize number of NOT*/ beaux->ABL=adapt_abl(beaux->ABL); /*count capacitance of leaves*/ } for (bebus=befig->BEBUS; bebus; bebus=bebus->NEXT) { for (biabl=bebus->BIABL; biabl; biabl=biabl->NEXT) { biabl->VALABL=inv_oper(biabl->VALABL,0); /*propagate NOT*/ biabl->CNDABL=inv_oper(biabl->CNDABL,0); /*propagate NOT*/ biabl->VALABL=build_negativ(biabl->VALABL); /*minimize NOT*/ biabl->CNDABL=build_negativ(biabl->CNDABL); } bebus->BIABL=adapt_bus(bebus->BIABL); /*count capacitance of leaves*/ } for (bereg=befig->BEREG; bereg; bereg=bereg->NEXT) { for (biabl=bereg->BIABL; biabl; biabl=biabl->NEXT) { biabl->VALABL=inv_oper(biabl->VALABL,0); /*propagate NOT*/ biabl->CNDABL=inv_oper(biabl->CNDABL,0); /*propagate NOT*/ biabl->VALABL=build_negativ(biabl->VALABL); /*minimize NOT*/ biabl->CNDABL=build_negativ(biabl->CNDABL); } bereg->BIABL=adapt_reg(bereg->BIABL); /*count capacitance of leaves*/ } for (bebux=befig->BEBUX; bebux; bebux=bebux->NEXT) { for (biabl=bebux->BIABL; biabl; biabl=biabl->NEXT) { biabl->VALABL=inv_oper(biabl->VALABL,0); /*propagate NOT*/ biabl->CNDABL=inv_oper(biabl->CNDABL,0); /*propagate NOT*/ biabl->VALABL=build_negativ(biabl->VALABL); /*minimize NOT*/ biabl->CNDABL=build_negativ(biabl->CNDABL); } bebux->BIABL=adapt_bus(bebux->BIABL); /*count capacitance of leaves*/ } }