/* ** estimate.c -- area/speed estimation generation for processing ** elements, extrapolates data from actual layouts ** Joseph B. Evans, 11/88 */ #include #include #include "estimate.h" #if defined(mips) #define log2(x) (log((x))/M_LN2) #endif /* mips */ adds(bits,add) struct pe *add; int bits; { if (a.fa_x + a.dff_x < a.fa_y + a.dff_y) { add->x = (a.fa_x>a.dff_x)?(a.fa_x):(a.dff_x); add->y = a.fa_y + a.dff_y; } else { add->x = a.fa_x + a.dff_x; add->y = (a.fa_y>a.dff_y)?(a.fa_y):(a.dff_y); } add->area = add->x * add->y; add->time = (double)(bits + 1)*max(t.fa,t.dff); } /* brent-kung parallel adder */ addp(bits,add) struct pe *add; int bits; { add->y = a.bkadd_y*(double)bits; add->x = a.bkadd_x * log2((double)bits); add->area = add->x * add->y; add->time = log2((double)bits)*t.bkadd; /* printf("\t%d bit adder: %g sq mm, %g ns\n",bits,add->area/CONV,add->time); */ } /* serial multiplier */ mults(b1,b2,mult) struct pe *mult; int b1,b2; { int bits = max(b1,b2); mult->x = a.fa_x + (double)(bits + 1)*a.dff_x; mult->y = max(a.fa_y,2.*a.dff_y); mult->area = mult->x * mult->y; mult->time = (pow((double)bits,2.) + 1.)*max(t.fa,t.dff); } /* serial-parallel multiplier */ multsp(b1,b2,mult) struct pe *mult; int b1,b2; { int bits = max(b1,b2); mult->x = a.multsp_x*(double)bits; mult->y = a.multsp_y; mult->area = mult->x * mult->y; mult->time = t.multsp*(double)bits; } /* parallel (array) multiplier */ multp(b1,b2,mult) struct pe *mult; int b1,b2; { mult->x = a.multp_x*(double)b1; mult->y = a.multp_y*(double)b2; mult->area = mult->x * mult->y; mult->time = t.multp*(double)(b1+b2); /* printf("\t%d by %d mult: %g sq mm, %g ns\n",cbits,dbits,mult->area/CONV,mult->time); */ } /* parallel (array) divider */ divp(b1,b2,div) struct pe *div; int b1,b2; { multp(b1,b2,div); div->area *= 2.5; div->time *= 2; /* printf("\t%d by %d div: %g sq mm, %g ns\n",cbits,dbits,div->area/CONV,div->time); */ } /* serial-parallel divider */ divsp(b1,b2,div) struct pe *div; int b1,b2; { multsp(b1,b2,div); div->area *= 2.5; div->time *= 2; /* printf("\t%d by %d div: %g sq mm, %g ns\n",cbits,dbits,div->area/CONV,div->time); */ } /* serial power-of-two quantizer-multiplier */ double ptqs(ebits,dbits,ptq) struct pe *ptq; int ebits,dbits; { ptq->x = (double)(ebits+dbits)*a.dff_x + a.ptql_x; ptq->y = 2.*(double)(ebits+dbits)*a.dff_y + a.ptql_y; ptq->area = ptq->x * ptq->y; ptq->time = (double)max(ebits,dbits)*(3.*t.dff + t.ptql); } /* parallel power-of-two quantizer-multiplier */ double ptqp(ebits,dbits,ptq) struct pe *ptq; int ebits,dbits; { ptq->x = (double)dbits*a.ptqs_x + (double)ebits*a.ptqq_x; ptq->y = (double)ebits*max(a.ptqs_y,a.ptqq_y); ptq->area = ptq->x * ptq->y; ptq->time = (double)(dbits)*t.ptqs + (double)ebits*t.ptqq; /* printf("\t%d by %d ptq: %g sq mm, %g ns\n",ebits,dbits,*area/CONV,*time); */ } /* static ram read and write */ double sram(bits,words,ram) struct pe *ram; int bits,words; { ram->x = (double)words*a.sram_x; ram->y = (double)bits*a.sram_y; ram->area = ram->x * ram->y; ram->time = t.sramr + t.sramw; /* printf("\t%d bits by %d words ram: %g sq mm, %g ns\n",bits,words,ram->area/CONV,ram->time); */ } /* static ram row decoder */ double ramrow(words,row) struct pe *row; int words; { row->x = a.ramrow_x*(double)words; row->y = a.ramrow_y*log2((double)words); row->area = row->x * row->y; row->time = t.ramrow*log2((double)words); /* printf("\t%d word row decoder: %g sq mm, %g ns\n",words,row->area/CONV,row->time); */ } /* latch (word) */ double latch(bits,latch) struct pe *latch; int bits; { latch->x = a.latch_x; latch->y = (double)bits*a.latch_y; latch->area = latch->x * latch->y; latch->time = t.latch; } /* variable step size update circuitry */ double vs_up(m0,m1,ss,vs_update) struct pe *vs_update; int m0,m1,ss; { vs_update->x = (double)max(m0,m1)*a.vsupl_x + (double)ss*a.vsups_x; vs_update->y = max(a.vsupl_y,a.vsups_y); vs_update->area = vs_update->x * vs_update->y; vs_update->time = (double)max(m0,m1)*t.vsupl + (double)ss*t.vsups; } /* variable step size parallel shift circuitry */ double vs_shftp(dbits,ss,vs_shift) struct pe *vs_shift; int dbits,ss; { vs_shift->x = (double)dbits*a.vsshft_x; vs_shift->y = (double)ss*a.vsshft_y; vs_shift->area = vs_shift->x * vs_shift->y; vs_shift->time = (double)(dbits)*t.vsshft; } /* variable step size serial shift circuitry */ double vs_shfts(dbits,ss,vs_shift) struct pe *vs_shift; int dbits,ss; { vs_shift->x = 2.*(double)(dbits+ss)*a.dff_x + a.vssl_x; vs_shift->y = a.dff_y; vs_shift->area = vs_shift->x * vs_shift->y; vs_shift->time = (double)max(dbits,ss)*(3.*t.dff + t.vssl); } /* MPE glue circuitry */ double glue(taps,glue) struct pe *glue; int taps; { glue->x = (double)taps*a.dff_x + (double)(taps-1)*a.dff_x + (double)taps*a.dff_x; glue->y = 4.*a.dff_y; glue->area = glue->x * glue->y; glue->time = 3.*t.dff; }