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 display_abl(chain_list* abl) { static int first=1; /*flags for braces*/ int sig_first=0; int oper; if (!abl) { fprintf (stderr,"(null)"); fflush(stderr); return; } if (ABL_ATOM (abl)) { /* Traitement atomique */ fprintf (stderr,"%s", ABL_ATOM_VALUE (abl)); fflush(stderr); return; } oper=ABL_OPER(abl); /*memorisation de l'operateur*/ /*operateur unaire*/ switch (oper) { case ABL_NOT: fprintf (stderr,"%s ",getabloperuppername(oper)); fflush(stderr); display_abl (ABL_CADR (abl)); return; case ABL_STABLE: display_abl (ABL_CADR (abl)); fprintf (stderr," '%s",getabloperuppername(oper)); fflush(stderr); return; } /*need of brace?*/ if (first) {first=0; sig_first=1;} else fprintf (stderr,"("); fflush(stderr); /* Traitement des autres operateurs */ for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) { display_abl(ABL_CAR(abl)); /* Un operateur en moins que le nombre d'arguments */ if (ABL_CDR (abl)) fprintf (stderr," %s ",getabloperuppername(oper)); fflush(stderr); } if (sig_first) first=1; else fprintf(stderr,")"); fflush(stderr); }
static note_list* eval_note(note_list* all_note, cell_list* cell, input_list *entry, int size) { port_list* port; note_list* note; float latest=0, delay, R=0; int source_positiv, dest_positiv, cost; chain_list* portchain; /*operator too big*/ if (size<ABL_ARITY(cell->ABL)) return all_note; source_positiv=is_source_positiv(ABL_OPER(cell->ABL)); dest_positiv=is_dest_positiv(ABL_OPER(cell->ABL),ABL_ARITY(cell->ABL)); /*operator no matches*/ if (source_positiv==-1 || dest_positiv==-1) return all_note; /*eval cost */ cost=size/ABL_ARITY(cell->ABL)+size%ABL_ARITY(cell->ABL); /*search if there is already a couple of this arity*/ for (note=all_note; note; note=note->NEXT) { if (note->ARITY==ABL_ARITY(cell->ABL)) { /*if worse than last record, skip it*/ if (dest_positiv) { if (cost>note->COST) return all_note; } else if (cost>note->NEG_COST) return all_note; break; } } /*eval delay*/ for (portchain=ABL_CDR(cell->ABL); portchain; portchain=portchain->NEXT) { port=(port_list*) ABL_ATOM_VALUE(ABL_CAR(portchain)); delay=port->T; delay+=source_positiv?entry->DELAY:entry->NEG_DELAY; /*sortance=1*/ delay+= port->C * (source_positiv?entry->R:entry->NEG_R); if (delay>latest) {latest=delay; R=port->R;} if (note) { /*if worse than last record, skip it*/ if (dest_positiv) { if (latest>=note->DELAY) return all_note; } else if (latest>=note->NEG_DELAY) return all_note; } entry=entry->NEXT; } /*create a new couple if doesn't exist*/ if (!note) { note=newnote(); note->NEXT=all_note; all_note=note; note->ARITY=ABL_ARITY(cell->ABL); } /*take new solution*/ if (dest_positiv) { note->DELAY=latest; note->R=R; note->COST=cost; note->CELL=cell; } else { note->NEG_DELAY=latest; note->NEG_R=R; note->NEG_COST=cost; note->NEG_CELL=cell; } return all_note; }
extern input_list* unflatten_area(input_list *entry, int entry_number) { input_list *pred = NULL, *input, *new_input; chain_list* abl; cell_list* cell; note_list* note, *all_note=NULL, *best_note; int cell_source_positiv, neg_cell_source_positiv; /*flag*/ if (!entry) { fprintf(stderr,"unflatten_area: no input\n"); exit(1); } /*test all the simple logic library*/ for (cell=getcell_oper_lib(); cell; cell=cell->NEXT) { all_note=eval_note(all_note, cell, entry, entry_number); } /*no result pattern, impossible to map, signal it to caller function*/ if (!all_note) return entry; /*take the best for a positiv and negativ results*/ best_note=all_note; best_note->AVERAGE_COST=(best_note->COST+best_note->NEG_COST)/2; for (note=all_note->NEXT; note; note=note->NEXT) { note->AVERAGE_COST=(note->COST+note->NEG_COST)/2; if (note->AVERAGE_COST<best_note->AVERAGE_COST) best_note=note; else if (note->AVERAGE_COST==best_note->AVERAGE_COST && note->ARITY>best_note->ARITY) best_note=note; else if (note->AVERAGE_COST==best_note->AVERAGE_COST && note->ARITY==best_note->ARITY && note->DELAY+note->NEG_DELAY<best_note->DELAY+best_note->NEG_DELAY) best_note=note; } /*one of those cells are missing, impossible to unflat*/ if (!best_note->CELL || !best_note->NEG_CELL) { fprintf(stderr, "unflatten_area: opposite cell of %s is missing (%d inputs)\n", best_note->CELL?best_note->CELL->NAME:best_note->NEG_CELL->NAME, entry_number); exit(1); } /*build new input*/ new_input=newinput(); new_input->DELAY=best_note->DELAY; new_input->NEG_DELAY=best_note->NEG_DELAY; new_input->R=best_note->R; new_input->NEG_R=best_note->NEG_R; new_input->ABL=createabloper(ABL_OPER(best_note->CELL->ABL)); new_input->NEG_ABL=createabloper(ABL_OPER(best_note->NEG_CELL->ABL)); cell_source_positiv=is_source_positiv(ABL_OPER(best_note->CELL->ABL)); neg_cell_source_positiv=is_source_positiv( ABL_OPER(best_note->NEG_CELL->ABL)); /*put operands*/ for (input=entry; input; input=input->NEXT) { if (best_note->ARITY==0) break; best_note->ARITY--; /*positiv*/ if (cell_source_positiv) { abl=input->ABL; input->ABL=NULL; /* protect from freeinput() */ } else { abl=input->NEG_ABL; input->NEG_ABL=NULL; /* protect from freeinput() */ } ABL_CDR(new_input->ABL)=addchain(ABL_CDR(new_input->ABL),abl); /*opposite*/ if (neg_cell_source_positiv) { if (input->ABL) abl=input->ABL; else abl=dupablexpr(abl); /*already used above*/ input->ABL=NULL; /* protect from freeinput() */ } else { if (input->NEG_ABL) abl=input->NEG_ABL; else abl=dupablexpr(abl); /*already used above*/ input->NEG_ABL=NULL; /* protect from freeinput() */ } ABL_CDR(new_input->NEG_ABL)=addchain(ABL_CDR(new_input->NEG_ABL),abl); pred=input; } pred->NEXT=NULL; freeinput(entry); freenote(all_note); return sort_input(input,new_input); /*return a sort list*/ }