📄 time.c.svn-base
字号:
//v4.1: Fixing double->int type conversion problems. EPSILON is added below to make sure
//the final int value is the correct one
//htree_int = (int) htree;
htree_int = (int) (htree + EPSILON);
if (htree_int % 2 == 0)
{
sub_v = sqrt (Ntwl * Ntbl) * rows_tag_subarray;
sub_h = sqrt (Ntwl * Ntbl) * cols_tag_subarray;
}
else
{
sub_v = sqrt (Ntwl * Ntbl / 2) * rows_tag_subarray;
sub_h = 2 * sqrt (Ntwl * Ntbl / 2) * cols_tag_subarray;
}
}
inter_v = MAX (sub_v, inter_v);
inter_h += sub_h;
*subbank_v = inter_v;
*subbank_h = inter_h;
}
else
{
rows_fa_subarray = (C / (B * Ndbl));
if(!force_tag) {
//v4.1: Fixing double->int type conversion problems. EPSILON is added below to make sure
//the final int value is the correct one
//tagbits = ADDRESS_BITS + EXTRA_TAG_BITS - (int) logtwo ((double) B);
tagbits = ADDRESS_BITS + EXTRA_TAG_BITS - (int) (logtwo ((double) B) + EPSILON);
}
else {
tagbits = force_tag_size;
}
cols_fa_subarray = (8 * B) + tagbits;
if (Ndbl == 1)
{
sub_v = rows_fa_subarray;
sub_h = cols_fa_subarray;
}
if (Ndbl == 2)
{
sub_v = rows_fa_subarray;
sub_h = 2 * cols_fa_subarray;
}
if (Ndbl > 2)
{
htree = logtwo ((double) (Ndbl));
//v4.1: Fixing double->int type conversion problems. EPSILON is added below to make sure
//the final int value is the correct one
//htree_int = (int) htree;
htree_int = (int) (htree + EPSILON);
if (htree_int % 2 == 0)
{
sub_v = sqrt (Ndbl) * rows_fa_subarray;
sub_h = sqrt (Ndbl) * cols_fa_subarray;
}
else
{
sub_v = sqrt (Ndbl / 2) * rows_fa_subarray;
sub_h = 2 * sqrt (Ndbl / 2) * cols_fa_subarray;
}
}
inter_v = sub_v;
inter_h = sub_h;
*subbank_v = inter_v;
*subbank_h = inter_h;
}
}
void subbanks_routing_power (char fullyassoc,
int A,
double NSubbanks,
double *subbank_h,double *subbank_v,powerDef *power)
{
double Ceq, Ceq_outdrv;
int i, blocks, htree_int, subbank_mod;
double htree, wire_cap, wire_cap_outdrv;
double start_h, start_v, line_h, line_v;
double dynPower = 0.0;
//*power = 0.0;
if (fullyassoc)
{
A = 1;
}
if (NSubbanks == 1.0 || NSubbanks == 2.0)
{
//*power = 0.0;
power->writeOp.dynamic = 0.0;
power->writeOp.leakage = 0.0;
power->readOp.dynamic = 0.0;
power->readOp.leakage = 0.0;
}
if (NSubbanks == 4.0)
{
/* calculation of address routing power */
wire_cap = GlobalCbitmetal * (*subbank_v);
Ceq = draincap (Wdecdrivep, PCH, 1) + draincap (Wdecdriven, NCH, 1) +
gatecap (Wdecdrivep + Wdecdriven, 0.0);
dynPower += 2 * ADDRESS_BITS * Ceq * .5 * VddPow * VddPow;
Ceq = draincap (Wdecdrivep, PCH, 1) + draincap (Wdecdriven, NCH, 1) +
wire_cap;
dynPower += 2 * ADDRESS_BITS * Ceq * .5 * VddPow * VddPow;
/* calculation of out driver power */
wire_cap_outdrv = Cbitmetal * (*subbank_v);
Ceq_outdrv =
draincap (Wsenseextdrv1p, PCH, 1) + draincap (Wsenseextdrv1n, NCH,
1) +
gatecap (Wsenseextdrv2n + Wsenseextdrv2p, 10.0 / FUDGEFACTOR);
dynPower += 2 * Ceq_outdrv * VddPow * VddPow * .5 * BITOUT * A * muxover;
Ceq_outdrv =
draincap (Wsenseextdrv2p, PCH, 1) + draincap (Wsenseextdrv2n, NCH,
1) + wire_cap_outdrv;
dynPower += 2 * Ceq_outdrv * VddPow * VddPow * .5 * BITOUT * A * muxover;
}
if (NSubbanks == 8.0)
{
wire_cap = GlobalCbitmetal * (*subbank_v) + GlobalCwordmetal * (*subbank_h);
/* buffer stage */
Ceq = draincap (Wdecdrivep, PCH, 1) + draincap (Wdecdriven, NCH, 1) +
gatecap (Wdecdrivep + Wdecdriven, 0.0);
dynPower += 6 * ADDRESS_BITS * Ceq * .5 * VddPow * VddPow;
Ceq = draincap (Wdecdrivep, PCH, 1) + draincap (Wdecdriven, NCH, 1) +
wire_cap;
dynPower += 4 * ADDRESS_BITS * Ceq * .5 * VddPow * VddPow;
Ceq = draincap (Wdecdrivep, PCH, 1) + draincap (Wdecdriven, NCH, 1) +
(wire_cap - Cbitmetal * (*subbank_v));
dynPower += 2 * ADDRESS_BITS * Ceq * .5 * VddPow * VddPow;
/* calculation of out driver power */
wire_cap_outdrv = Cbitmetal * (*subbank_v) + Cwordmetal * (*subbank_h);
Ceq_outdrv =
draincap (Wsenseextdrv1p, PCH, 1) + draincap (Wsenseextdrv1n, NCH,
1) +
gatecap (Wsenseextdrv2n + Wsenseextdrv2p, 10.0 / FUDGEFACTOR);
dynPower += 6 * Ceq_outdrv * VddPow * VddPow * .5 * BITOUT * A * muxover;
Ceq_outdrv =
draincap (Wsenseextdrv2p, PCH, 1) + draincap (Wsenseextdrv2n, NCH,
1) + wire_cap_outdrv;
dynPower += 4 * Ceq_outdrv * VddPow * VddPow * .5 * BITOUT * A * muxover;
Ceq_outdrv =
draincap (Wsenseextdrv2p, PCH, 1) + draincap (Wsenseextdrv2n, NCH,
1) + (wire_cap_outdrv -
Cbitmetal *
(*subbank_v));
dynPower += 2 * Ceq_outdrv * VddPow * VddPow * .5 * BITOUT * A * muxover;
}
if (NSubbanks > 8.0)
{
blocks = (int) (NSubbanks / 8.0);
htree = logtwo ((double) (blocks));
//v4.1: Fixing double->int type conversion problems. EPSILON is added below to make sure
//the final int value is the correct one
//htree_int = (int) htree;
htree_int = (int) (htree + EPSILON);
if (htree_int % 2 == 0)
{
subbank_mod = htree_int;
start_h =
(*subbank_h * (powers (2, ((int) (logtwo (htree))) + 1) - 1));
start_v = *subbank_v;
}
else
{
subbank_mod = htree_int - 1;
start_h = (*subbank_h * (powers (2, (htree_int + 1) / 2) - 1));
start_v = *subbank_v;
}
if (subbank_mod == 0)
{
subbank_mod = 1;
}
line_v = start_v;
line_h = start_h;
for (i = 1; i <= blocks; i++)
{
wire_cap = line_v * GlobalCbitmetal + line_h * GlobalCwordmetal;
Ceq =
draincap (Wdecdrivep, PCH, 1) + draincap (Wdecdriven, NCH,
1) +
gatecap (Wdecdrivep + Wdecdriven, 0.0);
dynPower += 6 * ADDRESS_BITS * Ceq * .5 * VddPow * VddPow;
Ceq =
draincap (Wdecdrivep, PCH, 1) + draincap (Wdecdriven, NCH,
1) + wire_cap;
dynPower += 4 * ADDRESS_BITS * Ceq * .5 * VddPow * VddPow;
Ceq =
draincap (Wdecdrivep, PCH, 1) + draincap (Wdecdriven, NCH,
1) + (wire_cap -
Cbitmetal *
(*subbank_v));
dynPower += 2 * ADDRESS_BITS * Ceq * .5 * VddPow * VddPow;
/* calculation of out driver power */
wire_cap_outdrv = line_v * GlobalCbitmetal + line_h * GlobalCwordmetal;
Ceq_outdrv =
draincap (Wsenseextdrv1p, PCH, 1) + draincap (Wsenseextdrv1n, NCH,
1) +
gatecap (Wsenseextdrv2n + Wsenseextdrv2p, 10.0 / FUDGEFACTOR);
dynPower +=
6 * Ceq_outdrv * VddPow * VddPow * .5 * BITOUT * A * muxover;
Ceq_outdrv =
draincap (Wsenseextdrv2p, PCH, 1) + draincap (Wsenseextdrv2n, NCH,
1) +
wire_cap_outdrv;
dynPower +=
4 * Ceq_outdrv * VddPow * VddPow * .5 * BITOUT * A * muxover;
Ceq_outdrv =
draincap (Wsenseextdrv2p, PCH, 1) + draincap (Wsenseextdrv2n, NCH,
1) +
(wire_cap_outdrv - Cbitmetal * (*subbank_v));
dynPower +=
2 * Ceq_outdrv * VddPow * VddPow * .5 * BITOUT * A * muxover;
if (i % subbank_mod == 0)
{
line_v += 2 * (*subbank_v);
}
}
}
power->writeOp.dynamic = dynPower;
/*dt: still have to add leakage current*/
power->readOp.dynamic = dynPower;
/*dt: still have to add leakage current*/
}
double address_routing_delay (int C,int B,int A,
char fullyassoc,
int Ndwl,int Ndbl,double Nspd,int Ntwl,int Ntbl,int Ntspd,
double *NSubbanks,double *outrisetime,powerDef *power)
{
double Ceq,tf,nextinputtime,delay_stage1,delay_stage2;
double addr_h,addr_v;
double wire_cap, wire_res;
double lkgCurrent = 0.0;
double dynEnergy = 0.0;
double Cline, Cload;
//powerDef *thisPower;
/* Calculate rise time. Consider two inverters */
Ceq = draincap (Wdecdrivep, PCH, 1) + draincap (Wdecdriven, NCH, 1) +
gatecap (Wdecdrivep + Wdecdriven, 0.0);
tf = Ceq * transreson (Wdecdriven, NCH, 1);
nextinputtime = horowitz (0.0, tf, VTHINV360x240, VTHINV360x240, FALL) /
(VTHINV360x240);
Ceq = draincap (Wdecdrivep, PCH, 1) + draincap (Wdecdriven, NCH, 1) +
gatecap (Wdecdrivep + Wdecdriven, 0.0);
tf = Ceq * transreson (Wdecdriven, NCH, 1);
nextinputtime = horowitz (nextinputtime, tf, VTHINV360x240, VTHINV360x240,
RISE) / (1.0 - VTHINV360x240);
addr_h = 0;
addr_v = 0;
subbank_routing_length (C, B, A, fullyassoc, Ndbl, Nspd, Ndwl, Ntbl, Ntwl,
Ntspd, *NSubbanks, &addr_v, &addr_h);
wire_cap = GlobalCbitmetal * addr_v + addr_h * GlobalCwordmetal;
wire_res = (GlobalRwordmetal * addr_h + GlobalRbitmetal * addr_v) / 2.0;
/* buffer stage */
/*dt: added gate width calc and leakage from eCACTI */
Cline = *NSubbanks * ( gatecap(Wdecdrivep_first + Wdecdriven_first,0.0) + gatecap(Wtdecdrivep_first + Wtdecdriven_first,0.0) ) + wire_cap;
Cload = Cline / gatecap(1.0,0.0);
Waddrdrvn1 = Cload * SizingRatio /3;
Waddrdrvp1 = Cload * SizingRatio * 2/3;
Waddrdrvn2 = (Waddrdrvn1 + Waddrdrvp1) * SizingRatio * 1/3 ;
Waddrdrvp2 = (Waddrdrvn1 + Waddrdrvp1) * SizingRatio * 2/3 ;
Ceq = draincap(Waddrdrvp2,PCH,1)+draincap(Waddrdrvn2,NCH,1) +
gatecap(Waddrdrvn1+Waddrdrvp1,0.0);
tf = Ceq*transreson(Waddrdrvn2,NCH,1);
delay_stage1 = horowitz(nextinputtime,tf,VTHINV360x240,VTHINV360x240,FALL);
nextinputtime = horowitz(nextinputtime,tf,VTHINV360x240,VTHINV360x240,FALL)/(VTHINV360x240);
dynEnergy = ADDRESS_BITS*Ceq*.5*VddPow*VddPow;
lkgCurrent += ADDRESS_BITS*0.5*cmos_ileakage(Waddrdrvn2,Waddrdrvp2,Vt_bit_nmos_low,Vthn,Vt_bit_pmos_low,Vthp);
Ceq = draincap(Waddrdrvp1,PCH,1)+draincap(Waddrdrvn1,NCH,1) + wire_cap
+ *NSubbanks * (gatecap(Wdecdrivep_first+Wdecdriven_first,0.0) + gatecap(Wtdecdrivep_first+Wtdecdriven_first,0.0));
tf = Ceq*(transreson(Waddrdrvn1,NCH,1)+wire_res);
delay_stage2=horowitz(nextinputtime,tf,VTHINV360x240,VTHINV360x240,RISE);
nextinputtime = horowitz(nextinputtime,tf,VTHINV360x240,VTHINV360x240,RISE)/(1.0-VTHINV360x240);
dynEnergy += ADDRESS_BITS*Ceq*.5*VddPow*VddPow;
lkgCurrent += ADDRESS_BITS*0.5*cmos_ileakage(Waddrdrvn1,Waddrdrvp1,Vthn,Vt_bit_nmos_low,Vt_bit_pmos_low,Vthp);
*outrisetime = nextinputtime;
power->readOp.dynamic = dynEnergy;
power->readOp.leakage = lkgCurrent * VddPow;
// power for write op same as read op for address routing
power->writeOp.dynamic = dynEnergy;
power->writeOp.leakage = lkgCurrent * VddPow;
return(delay_stage1+delay_stage2);
}
/* Decoder delay: (see section 6.1 of tech report) */
/*dt: this is integrated from eCACTI. But we use want Energy per operation, not some measure of power, so no FREQ. */
double decoder_delay(int C, int B,int A,int Ndwl,int Ndbl,double Nspd,double NSubbanks,
double *Tdecdrive,double *Tdecoder1,double *Tdecoder2,double inrisetime,double *outrisetime, int *nor_inputs,powerDef *power)
{
int numstack, Nact;
//double Ceq,Req,Rwire,tf,nextinputtime,vth,tstep;
double Ceq,Req,Rwire,tf,nextinputtime,vth;
int l_predec_nor_v, l_predec_nor_h,rows,cols;
//double wire_cap, wire_res;
double lkgCurrent = 0.0, dynPower = 0.0;
int horizontal_edge = 0;
int nr_subarrays_left = 0, v_or_h = 0;
int horizontal_step = 0, vertical_step = 0;
int h_inv_predecode = 0, v_inv_predecode = 0;
int addr_bits_routed;
int i;
double this_delay;
//v4.1: Fixing double->int type conversion problems. EPSILON is added below to make sure
//the final int value is the correct one
//int addr_bits=(int)logtwo( (double)((double)C/(double)(B*A*Ndbl*Nspd)));
//addr_bits_routed = (int)logtwo( (double)((double)C/(double)B));
//int addr_bits=(int)logtwo( (double)((double)C/(double)(B*A*Ndbl*Nspd)));
//addr_bits_routed = (int)logtwo( (double)((double)C/(double)B));
int addr_bits=(int) (logtwo( (double)((double)C/(double)(B*A*Ndbl*Nspd))) + EPSILON);
addr_bits_routed = (int) (logtwo( (double)((double)C/(double)B)) + EPSILON);
//rows = C/(8*B*A*Ndbl*Nspd);
//cols = CHUNKSIZE*B*A*Nspd/Ndwl;
rows = (int) (C/(8*B*A*Ndbl*Nspd) + EPSILON);
cols = (int) (CHUNKSIZE*B*A*Nspd/Ndwl + EPSILON);
numstack =
(int) ceil((1.0/3.0)*logtwo( (double)((double)C/(double)(B*A*Ndbl*Nspd))));
if (numstack==0) numstack = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -