diff options
Diffstat (limited to 'src/gpuwattch/logic.cc')
| -rw-r--r-- | src/gpuwattch/logic.cc | 2099 |
1 files changed, 1186 insertions, 913 deletions
diff --git a/src/gpuwattch/logic.cc b/src/gpuwattch/logic.cc index 106b381..7f40189 100644 --- a/src/gpuwattch/logic.cc +++ b/src/gpuwattch/logic.cc @@ -29,217 +29,256 @@ * ***************************************************************************/ /******************************************************************** -* Modified by: * -* Jingwen Leng, Univeristy of Texas, Austin * -* Syed Gilani, University of Wisconsin–Madison * -* Tayler Hetherington, University of British Columbia * -* Ahmed ElTantawy, University of British Columbia * -********************************************************************/ + * Modified by: + ** Jingwen Leng, Univeristy of Texas, Austin * Syed Gilani, + *University of Wisconsin–Madison * Tayler Hetherington, + *University of British Columbia * Ahmed ElTantawy, University of + *British Columbia * + ********************************************************************/ #include "logic.h" -#define SP_BASE_POWER 0 +#define SP_BASE_POWER 0 #define SFU_BASE_POWER 0 //.67 -//extern double exClockRate; -//selection_logic -selection_logic::selection_logic( - bool _is_default, - int win_entries_, - int issue_width_, - const InputParameter *configure_interface, - enum Device_ty device_ty_, - enum Core_type core_ty_) - //const ParseXML *_XML_interface) - :is_default(_is_default), - win_entries(win_entries_), - issue_width(issue_width_), - device_ty(device_ty_), - core_ty(core_ty_) - { - //uca_org_t result2; - l_ip=*configure_interface; - local_result = init_interface(&l_ip); - //init_tech_params(l_ip.F_sz_um, false); - //win_entries=numIBEntries;//IQentries; - //issue_width=issueWidth; - selection_power(); - double sckRation = g_tp.sckt_co_eff; - power.readOp.dynamic *= sckRation; - power.writeOp.dynamic *= sckRation; - power.searchOp.dynamic *= sckRation; +// extern double exClockRate; +// selection_logic +selection_logic::selection_logic(bool _is_default, int win_entries_, + int issue_width_, + const InputParameter *configure_interface, + enum Device_ty device_ty_, + enum Core_type core_ty_) + // const ParseXML *_XML_interface) + : is_default(_is_default), + win_entries(win_entries_), + issue_width(issue_width_), + device_ty(device_ty_), + core_ty(core_ty_) { + // uca_org_t result2; + l_ip = *configure_interface; + local_result = init_interface(&l_ip); + // init_tech_params(l_ip.F_sz_um, false); + // win_entries=numIBEntries;//IQentries; + // issue_width=issueWidth; + selection_power(); + double sckRation = g_tp.sckt_co_eff; + power.readOp.dynamic *= sckRation; + power.writeOp.dynamic *= sckRation; + power.searchOp.dynamic *= sckRation; - double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty); - power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction; - } + double long_channel_device_reduction = + longer_channel_device_reduction(device_ty, core_ty); + power.readOp.longer_channel_leakage = + power.readOp.leakage * long_channel_device_reduction; +} -void selection_logic::selection_power() -{//based on cost effective superscalar processor TR pp27-31 +void selection_logic::selection_power() { // based on cost effective + // superscalar processor TR pp27-31 double Ctotal, Cor, Cpencode; int num_arbiter; double WSelORn, WSelORprequ, WSelPn, WSelPp, WSelEnn, WSelEnp; - //TODO: the 0.8um process data is used. - WSelORn = 12.5 * l_ip.F_sz_um;//this was 10 micron for the 0.8 micron process - WSelORprequ = 50 * l_ip.F_sz_um;//this was 40 micron for the 0.8 micron process - WSelPn = 12.5 * l_ip.F_sz_um;//this was 10mcron for the 0.8 micron process - WSelPp = 18.75 * l_ip.F_sz_um;//this was 15 micron for the 0.8 micron process - WSelEnn = 6.25 * l_ip.F_sz_um;//this was 5 micron for the 0.8 micron process - WSelEnp = 12.5 * l_ip.F_sz_um;//this was 10 micron for the 0.8 micron process - + // TODO: the 0.8um process data is used. + WSelORn = + 12.5 * l_ip.F_sz_um; // this was 10 micron for the 0.8 micron process + WSelORprequ = + 50 * l_ip.F_sz_um; // this was 40 micron for the 0.8 micron process + WSelPn = 12.5 * l_ip.F_sz_um; // this was 10mcron for the 0.8 micron process + WSelPp = + 18.75 * l_ip.F_sz_um; // this was 15 micron for the 0.8 micron process + WSelEnn = 6.25 * l_ip.F_sz_um; // this was 5 micron for the 0.8 micron + // process + WSelEnp = + 12.5 * l_ip.F_sz_um; // this was 10 micron for the 0.8 micron process - Ctotal=0; - num_arbiter=1; - while(win_entries > 4) - { - win_entries = (int)ceil((double)win_entries / 4.0); - num_arbiter += win_entries; - } - //the 4-input OR logic to generate anyreq - Cor = 4 * drain_C_(WSelORn,NCH,1,1, g_tp.cell_h_def) + drain_C_(WSelORprequ,PCH,1,1, g_tp.cell_h_def); - power.readOp.gate_leakage = cmos_Ig_leakage(WSelORn, WSelORprequ, 4, nor)*g_tp.peri_global.Vdd; + Ctotal = 0; + num_arbiter = 1; + while (win_entries > 4) { + win_entries = (int)ceil((double)win_entries / 4.0); + num_arbiter += win_entries; + } + // the 4-input OR logic to generate anyreq + Cor = 4 * drain_C_(WSelORn, NCH, 1, 1, g_tp.cell_h_def) + + drain_C_(WSelORprequ, PCH, 1, 1, g_tp.cell_h_def); + power.readOp.gate_leakage = + cmos_Ig_leakage(WSelORn, WSelORprequ, 4, nor) * g_tp.peri_global.Vdd; - //The total capacity of the 4-bit priority encoder - Cpencode = drain_C_(WSelPn,NCH,1, 1, g_tp.cell_h_def) + drain_C_(WSelPp,PCH,1, 1, g_tp.cell_h_def) + - 2*drain_C_(WSelPn,NCH,1, 1, g_tp.cell_h_def) + drain_C_(WSelPp,PCH,2, 1, g_tp.cell_h_def) + - 3*drain_C_(WSelPn,NCH,1, 1, g_tp.cell_h_def) + drain_C_(WSelPp,PCH,3, 1, g_tp.cell_h_def) + - 4*drain_C_(WSelPn,NCH,1, 1, g_tp.cell_h_def) + drain_C_(WSelPp,PCH,4, 1, g_tp.cell_h_def) +//precompute priority logic - 2*4*gate_C(WSelEnn+WSelEnp,20.0)+ - 4*drain_C_(WSelEnn,NCH,1, 1, g_tp.cell_h_def) + 2*4*drain_C_(WSelEnp,PCH,1, 1, g_tp.cell_h_def)+//enable logic - (2*4+2*3+2*2+2)*gate_C(WSelPn+WSelPp,10.0);//requests signal + // The total capacity of the 4-bit priority encoder + Cpencode = + drain_C_(WSelPn, NCH, 1, 1, g_tp.cell_h_def) + + drain_C_(WSelPp, PCH, 1, 1, g_tp.cell_h_def) + + 2 * drain_C_(WSelPn, NCH, 1, 1, g_tp.cell_h_def) + + drain_C_(WSelPp, PCH, 2, 1, g_tp.cell_h_def) + + 3 * drain_C_(WSelPn, NCH, 1, 1, g_tp.cell_h_def) + + drain_C_(WSelPp, PCH, 3, 1, g_tp.cell_h_def) + + 4 * drain_C_(WSelPn, NCH, 1, 1, g_tp.cell_h_def) + + drain_C_(WSelPp, PCH, 4, 1, + g_tp.cell_h_def) + // precompute priority logic + 2 * 4 * gate_C(WSelEnn + WSelEnp, 20.0) + + 4 * drain_C_(WSelEnn, NCH, 1, 1, g_tp.cell_h_def) + + 2 * 4 * drain_C_(WSelEnp, PCH, 1, 1, g_tp.cell_h_def) + // enable logic + (2 * 4 + 2 * 3 + 2 * 2 + 2) * + gate_C(WSelPn + WSelPp, 10.0); // requests signal - Ctotal += issue_width * num_arbiter*(Cor+Cpencode); + Ctotal += issue_width * num_arbiter * (Cor + Cpencode); - power.readOp.dynamic = Ctotal*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*2;//2 means the abitration signal need to travel round trip - power.readOp.leakage = issue_width * num_arbiter * - (cmos_Isub_leakage(WSelPn, WSelPp, 2, nor)/*approximate precompute with a nor gate*///grant1p - + cmos_Isub_leakage(WSelPn, WSelPp, 3, nor)//grant2p - + cmos_Isub_leakage(WSelPn, WSelPp, 4, nor)//grant3p - + cmos_Isub_leakage(WSelEnn, WSelEnp, 2, nor)*4//enable logic - + cmos_Isub_leakage(WSelEnn, WSelEnp, 1, inv)*2*3//for each grant there are two inverters, there are 3 grant sIsubnals - )*g_tp.peri_global.Vdd; - power.readOp.gate_leakage = issue_width * num_arbiter * - (cmos_Ig_leakage(WSelPn, WSelPp, 2, nor)/*approximate precompute with a nor gate*///grant1p - + cmos_Ig_leakage(WSelPn, WSelPp, 3, nor)//grant2p - + cmos_Ig_leakage(WSelPn, WSelPp, 4, nor)//grant3p - + cmos_Ig_leakage(WSelEnn, WSelEnp, 2, nor)*4//enable logic - + cmos_Ig_leakage(WSelEnn, WSelEnp, 1, inv)*2*3//for each grant there are two inverters, there are 3 grant signals - )*g_tp.peri_global.Vdd; + power.readOp.dynamic = + Ctotal * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd * + 2; // 2 means the abitration signal need to travel round trip + power.readOp.leakage = + issue_width * num_arbiter * + (cmos_Isub_leakage( + WSelPn, WSelPp, 2, + nor) /*approximate precompute with a nor gate*/ // grant1p + + cmos_Isub_leakage(WSelPn, WSelPp, 3, nor) // grant2p + + cmos_Isub_leakage(WSelPn, WSelPp, 4, nor) // grant3p + + cmos_Isub_leakage(WSelEnn, WSelEnp, 2, nor) * 4 // enable logic + + cmos_Isub_leakage(WSelEnn, WSelEnp, 1, inv) * 2 * + 3 // for each grant there are two inverters, there are 3 grant + // sIsubnals + ) * + g_tp.peri_global.Vdd; + power.readOp.gate_leakage = + issue_width * num_arbiter * + (cmos_Ig_leakage( + WSelPn, WSelPp, 2, + nor) /*approximate precompute with a nor gate*/ // grant1p + + cmos_Ig_leakage(WSelPn, WSelPp, 3, nor) // grant2p + + cmos_Ig_leakage(WSelPn, WSelPp, 4, nor) // grant3p + + cmos_Ig_leakage(WSelEnn, WSelEnp, 2, nor) * 4 // enable logic + + cmos_Ig_leakage(WSelEnn, WSelEnp, 1, inv) * 2 * + 3 // for each grant there are two inverters, there are 3 grant + // signals + ) * + g_tp.peri_global.Vdd; } - dep_resource_conflict_check::dep_resource_conflict_check( - const InputParameter *configure_interface, - const CoreDynParam & dyn_p_, - int compare_bits_, - bool _is_default) - : l_ip(*configure_interface), - coredynp(dyn_p_), - compare_bits(compare_bits_), - is_default(_is_default) -{ - Wcompn = 25 * l_ip.F_sz_um;//this was 20.0 micron for the 0.8 micron process - Wevalinvp = 25 * l_ip.F_sz_um;//this was 20.0 micron for the 0.8 micron process - Wevalinvn = 100 * l_ip.F_sz_um;//this was 80.0 mcron for the 0.8 micron process - Wcomppreequ = 50 * l_ip.F_sz_um;//this was 40.0 micron for the 0.8 micron process - WNORn = 6.75 * l_ip.F_sz_um;//this was 5.4 micron for the 0.8 micron process - WNORp = 38.125 * l_ip.F_sz_um;//this was 30.5 micron for the 0.8 micron process - - local_result = init_interface(&l_ip); + const InputParameter *configure_interface, const CoreDynParam &dyn_p_, + int compare_bits_, bool _is_default) + : l_ip(*configure_interface), + coredynp(dyn_p_), + compare_bits(compare_bits_), + is_default(_is_default) { + Wcompn = 25 * l_ip.F_sz_um; // this was 20.0 micron for the 0.8 micron + // process + Wevalinvp = + 25 * l_ip.F_sz_um; // this was 20.0 micron for the 0.8 micron process + Wevalinvn = + 100 * l_ip.F_sz_um; // this was 80.0 mcron for the 0.8 micron process + Wcomppreequ = + 50 * l_ip.F_sz_um; // this was 40.0 micron for the 0.8 micron process + WNORn = 6.75 * l_ip.F_sz_um; // this was 5.4 micron for the 0.8 micron + // process + WNORp = + 38.125 * l_ip.F_sz_um; // this was 30.5 micron for the 0.8 micron process - if (coredynp.core_ty==Inorder) - compare_bits += 16 + 8 + 8;//TODO: opcode bits + log(shared resources) + REG TAG BITS-->opcode comparator - else - compare_bits += 16 + 8 + 8; + local_result = init_interface(&l_ip); - conflict_check_power(); - double sckRation = g_tp.sckt_co_eff; - power.readOp.dynamic *= sckRation; - power.writeOp.dynamic *= sckRation; - power.searchOp.dynamic *= sckRation; + if (coredynp.core_ty == Inorder) + compare_bits += 16 + 8 + 8; // TODO: opcode bits + log(shared resources) + + // REG TAG BITS-->opcode comparator + else + compare_bits += 16 + 8 + 8; + conflict_check_power(); + double sckRation = g_tp.sckt_co_eff; + power.readOp.dynamic *= sckRation; + power.writeOp.dynamic *= sckRation; + power.searchOp.dynamic *= sckRation; } -void dep_resource_conflict_check::conflict_check_power() -{ - double Ctotal; - int num_comparators; - num_comparators = 3*((coredynp.decodeW) * (coredynp.decodeW)-coredynp.decodeW);//2(N*N-N) is used for source to dest comparison, (N*N-N) is used for dest to dest comparision. - //When decode-width ==1, no dcl logic - - Ctotal = num_comparators * compare_cap(); - //printf("%i,%s\n",XML_interface->sys.core[0].predictor.predictor_entries,XML_interface->sys.core[0].predictor.prediction_scheme); +void dep_resource_conflict_check::conflict_check_power() { + double Ctotal; + int num_comparators; + num_comparators = + 3 * + ((coredynp.decodeW) * (coredynp.decodeW) - + coredynp.decodeW); // 2(N*N-N) is used for source to dest comparison, + // (N*N-N) is used for dest to dest comparision. + // When decode-width ==1, no dcl logic - power.readOp.dynamic=Ctotal*/*CLOCKRATE*/g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/*AF*/; - power.readOp.leakage=num_comparators*compare_bits*2*simplified_nmos_leakage(Wcompn, false); + Ctotal = num_comparators * compare_cap(); + // printf("%i,%s\n",XML_interface->sys.core[0].predictor.predictor_entries,XML_interface->sys.core[0].predictor.prediction_scheme); - double long_channel_device_reduction = longer_channel_device_reduction(Core_device, coredynp.core_ty); - power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction; - power.readOp.gate_leakage=num_comparators*compare_bits*2*cmos_Ig_leakage(Wcompn, 0, 2, nmos); + power.readOp.dynamic = + Ctotal * /*CLOCKRATE*/ g_tp.peri_global.Vdd * g_tp.peri_global.Vdd /*AF*/; + power.readOp.leakage = num_comparators * compare_bits * 2 * + simplified_nmos_leakage(Wcompn, false); + double long_channel_device_reduction = + longer_channel_device_reduction(Core_device, coredynp.core_ty); + power.readOp.longer_channel_leakage = + power.readOp.leakage * long_channel_device_reduction; + power.readOp.gate_leakage = + num_comparators * compare_bits * 2 * cmos_Ig_leakage(Wcompn, 0, 2, nmos); } /* estimate comparator power consumption (this comparator is similar to the tag-match structure in a CAM */ -double dep_resource_conflict_check::compare_cap() -{ +double dep_resource_conflict_check::compare_cap() { double c1, c2; - WNORp = WNORp * compare_bits/2.0;//resize the big NOR gate at the DCL according to fan in. + WNORp = WNORp * compare_bits / + 2.0; // resize the big NOR gate at the DCL according to fan in. /* bottom part of comparator */ - c2 = (compare_bits)*(drain_C_(Wcompn,NCH,1,1, g_tp.cell_h_def)+drain_C_(Wcompn,NCH,2,1, g_tp.cell_h_def))+ - drain_C_(Wevalinvp,PCH,1,1, g_tp.cell_h_def) + drain_C_(Wevalinvn,NCH,1,1, g_tp.cell_h_def); + c2 = (compare_bits) * (drain_C_(Wcompn, NCH, 1, 1, g_tp.cell_h_def) + + drain_C_(Wcompn, NCH, 2, 1, g_tp.cell_h_def)) + + drain_C_(Wevalinvp, PCH, 1, 1, g_tp.cell_h_def) + + drain_C_(Wevalinvn, NCH, 1, 1, g_tp.cell_h_def); /* top part of comparator */ - c1 = (compare_bits)*(drain_C_(Wcompn,NCH,1,1, g_tp.cell_h_def)+drain_C_(Wcompn,NCH,2,1, g_tp.cell_h_def)+ - drain_C_(Wcomppreequ,NCH,1,1, g_tp.cell_h_def)) + gate_C(WNORn + WNORp,10.0) + - drain_C_(WNORp,NCH,2,1, g_tp.cell_h_def) + compare_bits*drain_C_(WNORn,NCH,2,1, g_tp.cell_h_def); - return(c1 + c2); - + c1 = (compare_bits) * (drain_C_(Wcompn, NCH, 1, 1, g_tp.cell_h_def) + + drain_C_(Wcompn, NCH, 2, 1, g_tp.cell_h_def) + + drain_C_(Wcomppreequ, NCH, 1, 1, g_tp.cell_h_def)) + + gate_C(WNORn + WNORp, 10.0) + + drain_C_(WNORp, NCH, 2, 1, g_tp.cell_h_def) + + compare_bits * drain_C_(WNORn, NCH, 2, 1, g_tp.cell_h_def); + return (c1 + c2); } -void dep_resource_conflict_check::leakage_feedback(double temperature) -{ - l_ip.temp = (unsigned int)round(temperature/10.0)*10; - uca_org_t init_result = init_interface(&l_ip); // init_result is dummy +void dep_resource_conflict_check::leakage_feedback(double temperature) { + l_ip.temp = (unsigned int)round(temperature / 10.0) * 10; + uca_org_t init_result = init_interface(&l_ip); // init_result is dummy // This is part of conflict_check_power() - int num_comparators = 3*((coredynp.decodeW) * (coredynp.decodeW)-coredynp.decodeW);//2(N*N-N) is used for source to dest comparison, (N*N-N) is used for dest to dest comparision. - power.readOp.leakage=num_comparators*compare_bits*2*simplified_nmos_leakage(Wcompn, false); + int num_comparators = + 3 * + ((coredynp.decodeW) * (coredynp.decodeW) - + coredynp.decodeW); // 2(N*N-N) is used for source to dest comparison, + // (N*N-N) is used for dest to dest comparision. + power.readOp.leakage = num_comparators * compare_bits * 2 * + simplified_nmos_leakage(Wcompn, false); - double long_channel_device_reduction = longer_channel_device_reduction(Core_device, coredynp.core_ty); - power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction; - power.readOp.gate_leakage=num_comparators*compare_bits*2*cmos_Ig_leakage(Wcompn, 0, 2, nmos); + double long_channel_device_reduction = + longer_channel_device_reduction(Core_device, coredynp.core_ty); + power.readOp.longer_channel_leakage = + power.readOp.leakage * long_channel_device_reduction; + power.readOp.gate_leakage = + num_comparators * compare_bits * 2 * cmos_Ig_leakage(Wcompn, 0, 2, nmos); } -//TODO: add inverter and transmission gate base DFF. - -DFFCell::DFFCell( - bool _is_dram, - double _WdecNANDn, - double _WdecNANDp, - double _cell_load, - const InputParameter *configure_interface) -:is_dram(_is_dram), -cell_load(_cell_load), -WdecNANDn(_WdecNANDn), -WdecNANDp(_WdecNANDp) -{//this model is based on the NAND2 based DFF. - l_ip=*configure_interface; -// area.set_area(730*l_ip.F_sz_um*l_ip.F_sz_um); - area.set_area(5*compute_gate_area(NAND, 2,WdecNANDn,WdecNANDp, g_tp.cell_h_def) - + compute_gate_area(NAND, 2,WdecNANDn,WdecNANDn, g_tp.cell_h_def)); - +// TODO: add inverter and transmission gate base DFF. +DFFCell::DFFCell(bool _is_dram, double _WdecNANDn, double _WdecNANDp, + double _cell_load, const InputParameter *configure_interface) + : is_dram(_is_dram), + cell_load(_cell_load), + WdecNANDn(_WdecNANDn), + WdecNANDp(_WdecNANDp) { // this model is based on the NAND2 based DFF. + l_ip = *configure_interface; + // area.set_area(730*l_ip.F_sz_um*l_ip.F_sz_um); + area.set_area( + 5 * compute_gate_area(NAND, 2, WdecNANDn, WdecNANDp, g_tp.cell_h_def) + + compute_gate_area(NAND, 2, WdecNANDn, WdecNANDn, g_tp.cell_h_def)); } - -double DFFCell::fpfp_node_cap(unsigned int fan_in, unsigned int fan_out) -{ +double DFFCell::fpfp_node_cap(unsigned int fan_in, unsigned int fan_out) { double Ctotal = 0; - //printf("WdecNANDn = %E\n", WdecNANDn); + // printf("WdecNANDn = %E\n", WdecNANDn); /* part 1: drain cap of NAND gate */ - Ctotal += drain_C_(WdecNANDn, NCH, 2, 1, g_tp.cell_h_def, is_dram) + fan_in * drain_C_(WdecNANDp, PCH, 1, 1, g_tp.cell_h_def, is_dram); + Ctotal += drain_C_(WdecNANDn, NCH, 2, 1, g_tp.cell_h_def, is_dram) + + fan_in * drain_C_(WdecNANDp, PCH, 1, 1, g_tp.cell_h_def, is_dram); /* part 2: gate cap of NAND gates */ Ctotal += fan_out * gate_C(WdecNANDn + WdecNANDp, 0, is_dram); @@ -247,838 +286,1071 @@ double DFFCell::fpfp_node_cap(unsigned int fan_in, unsigned int fan_out) return Ctotal; } +void DFFCell::compute_DFF_cell() { + double c1, c2, c3, c4, c5, c6; + /* node 5 and node 6 are identical to node 1 in capacitance */ + c1 = c5 = c6 = fpfp_node_cap(2, 1); + c2 = fpfp_node_cap(2, 3); + c3 = fpfp_node_cap(3, 2); + c4 = fpfp_node_cap(2, 2); -void DFFCell::compute_DFF_cell() -{ - double c1, c2, c3, c4, c5, c6; - /* node 5 and node 6 are identical to node 1 in capacitance */ - c1 = c5 = c6 = fpfp_node_cap(2, 1); - c2 = fpfp_node_cap(2, 3); - c3 = fpfp_node_cap(3, 2); - c4 = fpfp_node_cap(2, 2); - - //cap-load of the clock signal in each Dff, actually the clock signal only connected to one NAND2 - clock_cap= 2 * gate_C(WdecNANDn + WdecNANDp, 0, is_dram); - e_switch.readOp.dynamic += (c4 + c1 + c2 + c3 + c5 + c6 + 2*cell_load)*0.5*g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;; + // cap-load of the clock signal in each Dff, actually the clock signal only + // connected to one NAND2 + clock_cap = 2 * gate_C(WdecNANDn + WdecNANDp, 0, is_dram); + e_switch.readOp.dynamic += (c4 + c1 + c2 + c3 + c5 + c6 + 2 * cell_load) * + 0.5 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd; + ; - /* no 1/2 for e_keep and e_clock because clock signal switches twice in one cycle */ - e_keep_1.readOp.dynamic += c3 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd ; - e_keep_0.readOp.dynamic += c2 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd ; - e_clock.readOp.dynamic += clock_cap* g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;; + /* no 1/2 for e_keep and e_clock because clock signal switches twice in one + * cycle */ + e_keep_1.readOp.dynamic += c3 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd; + e_keep_0.readOp.dynamic += c2 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd; + e_clock.readOp.dynamic += + clock_cap * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd; + ; - /* static power */ - e_switch.readOp.leakage += (cmos_Isub_leakage(WdecNANDn, WdecNANDp, 2, nand)*5//5 NAND2 and 1 NAND3 in a DFF - + cmos_Isub_leakage(WdecNANDn, WdecNANDn, 3, nand))*g_tp.peri_global.Vdd; - e_switch.readOp.gate_leakage += (cmos_Ig_leakage(WdecNANDn, WdecNANDp, 2, nand)*5//5 NAND2 and 1 NAND3 in a DFF - + cmos_Ig_leakage(WdecNANDn, WdecNANDn, 3, nand))*g_tp.peri_global.Vdd; - //printf("leakage =%E\n",cmos_Ileak(1, is_dram) ); + /* static power */ + e_switch.readOp.leakage += + (cmos_Isub_leakage(WdecNANDn, WdecNANDp, 2, nand) * + 5 // 5 NAND2 and 1 NAND3 in a DFF + + cmos_Isub_leakage(WdecNANDn, WdecNANDn, 3, nand)) * + g_tp.peri_global.Vdd; + e_switch.readOp.gate_leakage += + (cmos_Ig_leakage(WdecNANDn, WdecNANDp, 2, nand) * + 5 // 5 NAND2 and 1 NAND3 in a DFF + + cmos_Ig_leakage(WdecNANDn, WdecNANDn, 3, nand)) * + g_tp.peri_global.Vdd; + // printf("leakage =%E\n",cmos_Ileak(1, is_dram) ); } -Pipeline::Pipeline( - const InputParameter *configure_interface, - const CoreDynParam & dyn_p_, - enum Device_ty device_ty_, - bool _is_core_pipeline, - bool _is_default) -: l_ip(*configure_interface), - coredynp(dyn_p_), - device_ty(device_ty_), - is_core_pipeline(_is_core_pipeline), - is_default(_is_default), - num_piperegs(0.0) - - { - local_result = init_interface(&l_ip); - if (!coredynp.Embedded) - process_ind = true; - else - process_ind = false; - WNANDn = (process_ind)? 25 * l_ip.F_sz_um : g_tp.min_w_nmos_ ;//this was 20 micron for the 0.8 micron process - WNANDp = (process_ind)? 37.5 * l_ip.F_sz_um : g_tp.min_w_nmos_*pmos_to_nmos_sz_ratio();//this was 30 micron for the 0.8 micron process - load_per_pipeline_stage = 2*gate_C(WNANDn + WNANDp, 0, false); - compute(); - -} +Pipeline::Pipeline(const InputParameter *configure_interface, + const CoreDynParam &dyn_p_, enum Device_ty device_ty_, + bool _is_core_pipeline, bool _is_default) + : l_ip(*configure_interface), + coredynp(dyn_p_), + device_ty(device_ty_), + is_core_pipeline(_is_core_pipeline), + is_default(_is_default), + num_piperegs(0.0) -void Pipeline::compute() { - compute_stage_vector(); - DFFCell pipe_reg(false, WNANDn,WNANDp, load_per_pipeline_stage, &l_ip); - pipe_reg.compute_DFF_cell(); + local_result = init_interface(&l_ip); + if (!coredynp.Embedded) + process_ind = true; + else + process_ind = false; + WNANDn = + (process_ind) + ? 25 * l_ip.F_sz_um + : g_tp.min_w_nmos_; // this was 20 micron for the 0.8 micron process + WNANDp = (process_ind) + ? 37.5 * l_ip.F_sz_um + : g_tp.min_w_nmos_ * + pmos_to_nmos_sz_ratio(); // this was 30 micron for the + // 0.8 micron process + load_per_pipeline_stage = 2 * gate_C(WNANDn + WNANDp, 0, false); + compute(); +} - double clock_power_pipereg = num_piperegs * pipe_reg.e_clock.readOp.dynamic; - //******************pipeline power: currently, we average all the possibilities of the states of DFFs in the pipeline. A better way to do it is to consider - //the harming distance of two consecutive signals, However McPAT does not have plan to do this in near future as it focuses on worst case power. - double pipe_reg_power = num_piperegs * (pipe_reg.e_switch.readOp.dynamic+pipe_reg.e_keep_0.readOp.dynamic+pipe_reg.e_keep_1.readOp.dynamic)/3+clock_power_pipereg; - double pipe_reg_leakage = num_piperegs * pipe_reg.e_switch.readOp.leakage; - double pipe_reg_gate_leakage = num_piperegs * pipe_reg.e_switch.readOp.gate_leakage; - power.readOp.dynamic +=pipe_reg_power; - power.readOp.leakage +=pipe_reg_leakage; - power.readOp.gate_leakage +=pipe_reg_gate_leakage; - area.set_area(num_piperegs * pipe_reg.area.get_area()); +void Pipeline::compute() { + compute_stage_vector(); + DFFCell pipe_reg(false, WNANDn, WNANDp, load_per_pipeline_stage, &l_ip); + pipe_reg.compute_DFF_cell(); - double long_channel_device_reduction = longer_channel_device_reduction(device_ty, coredynp.core_ty); - power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction; + double clock_power_pipereg = num_piperegs * pipe_reg.e_clock.readOp.dynamic; + //******************pipeline power: currently, we average all the + // possibilities of the states of DFFs in the pipeline. A better way to do it + // is to consider the harming distance of two consecutive signals, However + // McPAT does not have plan to do this in near future as it focuses on worst + // case power. + double pipe_reg_power = + num_piperegs * + (pipe_reg.e_switch.readOp.dynamic + pipe_reg.e_keep_0.readOp.dynamic + + pipe_reg.e_keep_1.readOp.dynamic) / + 3 + + clock_power_pipereg; + double pipe_reg_leakage = num_piperegs * pipe_reg.e_switch.readOp.leakage; + double pipe_reg_gate_leakage = + num_piperegs * pipe_reg.e_switch.readOp.gate_leakage; + power.readOp.dynamic += pipe_reg_power; + power.readOp.leakage += pipe_reg_leakage; + power.readOp.gate_leakage += pipe_reg_gate_leakage; + area.set_area(num_piperegs * pipe_reg.area.get_area()); + double long_channel_device_reduction = + longer_channel_device_reduction(device_ty, coredynp.core_ty); + power.readOp.longer_channel_leakage = + power.readOp.leakage * long_channel_device_reduction; - double sckRation = g_tp.sckt_co_eff; - power.readOp.dynamic *= sckRation; - power.writeOp.dynamic *= sckRation; - power.searchOp.dynamic *= sckRation; - double macro_layout_overhead = g_tp.macro_layout_overhead; - if (!coredynp.Embedded) - area.set_area(area.get_area()*macro_layout_overhead); + double sckRation = g_tp.sckt_co_eff; + power.readOp.dynamic *= sckRation; + power.writeOp.dynamic *= sckRation; + power.searchOp.dynamic *= sckRation; + double macro_layout_overhead = g_tp.macro_layout_overhead; + if (!coredynp.Embedded) + area.set_area(area.get_area() * macro_layout_overhead); } -void Pipeline::compute_stage_vector() -{ - double num_stages, tot_stage_vector, per_stage_vector; - int opcode_length = coredynp.x86? coredynp.micro_opcode_length:coredynp.opcode_length; - //Hthread = thread_clock_gated? 1:num_thread; - - if (!is_core_pipeline) - { - num_piperegs=l_ip.pipeline_stages*l_ip.per_stage_vector;//The number of pipeline stages are calculated based on the achievable throughput and required throughput - } - else - { - if (coredynp.core_ty==Inorder) - { - /* assume 6 pipe stages and try to estimate bits per pipe stage */ - /* pipe stage 0/IF */ - num_piperegs += coredynp.pc_width*2*coredynp.num_hthreads; - /* pipe stage IF/ID */ - num_piperegs += coredynp.fetchW*(coredynp.instruction_length + coredynp.pc_width)*coredynp.num_hthreads; - /* pipe stage IF/ThreadSEL */ - if (coredynp.multithreaded) num_piperegs += coredynp.num_hthreads*coredynp.perThreadState; //8 bit thread states - /* pipe stage ID/EXE */ - num_piperegs += coredynp.decodeW*(coredynp.instruction_length + coredynp.pc_width + pow(2.0,opcode_length)+ 2*coredynp.int_data_width)*coredynp.num_hthreads; - /* pipe stage EXE/MEM */ - num_piperegs += coredynp.issueW*(3 * coredynp.arch_ireg_width + pow(2.0,opcode_length) + 8*2*coredynp.int_data_width/*+2*powers (2,reg_length)*/); - /* pipe stage MEM/WB the 2^opcode_length means the total decoded signal for the opcode*/ - num_piperegs += coredynp.issueW*(2*coredynp.int_data_width + pow(2.0,opcode_length) + 8*2*coredynp.int_data_width/*+2*powers (2,reg_length)*/); -// /* pipe stage 5/6 */ -// num_piperegs += issueWidth*(data_width + powers (2,opcode_length)/*+2*powers (2,reg_length)*/); -// /* pipe stage 6/7 */ -// num_piperegs += issueWidth*(data_width + powers (2,opcode_length)/*+2*powers (2,reg_length)*/); -// /* pipe stage 7/8 */ -// num_piperegs += issueWidth*(data_width + powers (2,opcode_length)/**2*powers (2,reg_length)*/); -// /* assume 50% extra in control signals (rule of thumb) */ - num_stages=6; +void Pipeline::compute_stage_vector() { + double num_stages, tot_stage_vector, per_stage_vector; + int opcode_length = + coredynp.x86 ? coredynp.micro_opcode_length : coredynp.opcode_length; + // Hthread = thread_clock_gated? 1:num_thread; - } - else - { - /* assume 12 stage pipe stages and try to estimate bits per pipe stage */ - /*OOO: Fetch, decode, rename, IssueQ, dispatch, regread, EXE, MEM, WB, CM */ + if (!is_core_pipeline) { + num_piperegs = l_ip.pipeline_stages * + l_ip.per_stage_vector; // The number of pipeline stages are + // calculated based on the achievable + // throughput and required throughput + } else { + if (coredynp.core_ty == Inorder) { + /* assume 6 pipe stages and try to estimate bits per pipe stage */ + /* pipe stage 0/IF */ + num_piperegs += coredynp.pc_width * 2 * coredynp.num_hthreads; + /* pipe stage IF/ID */ + num_piperegs += coredynp.fetchW * + (coredynp.instruction_length + coredynp.pc_width) * + coredynp.num_hthreads; + /* pipe stage IF/ThreadSEL */ + if (coredynp.multithreaded) + num_piperegs += coredynp.num_hthreads * + coredynp.perThreadState; // 8 bit thread states + /* pipe stage ID/EXE */ + num_piperegs += coredynp.decodeW * + (coredynp.instruction_length + coredynp.pc_width + + pow(2.0, opcode_length) + 2 * coredynp.int_data_width) * + coredynp.num_hthreads; + /* pipe stage EXE/MEM */ + num_piperegs += + coredynp.issueW * + (3 * coredynp.arch_ireg_width + pow(2.0, opcode_length) + + 8 * 2 * coredynp.int_data_width /*+2*powers (2,reg_length)*/); + /* pipe stage MEM/WB the 2^opcode_length means the total decoded signal + * for the opcode*/ + num_piperegs += + coredynp.issueW * + (2 * coredynp.int_data_width + pow(2.0, opcode_length) + + 8 * 2 * coredynp.int_data_width /*+2*powers (2,reg_length)*/); + // /* pipe stage 5/6 */ + // num_piperegs += issueWidth*(data_width + powers + //(2,opcode_length)/*+2*powers (2,reg_length)*/); + // /* pipe stage 6/7 */ + // num_piperegs += issueWidth*(data_width + powers + //(2,opcode_length)/*+2*powers (2,reg_length)*/); + // /* pipe stage 7/8 */ + // num_piperegs += issueWidth*(data_width + powers + //(2,opcode_length)/**2*powers (2,reg_length)*/); + // /* assume 50% extra in control signals (rule of thumb) + //*/ + num_stages = 6; - /* pipe stage 0/1F*/ - num_piperegs += coredynp.pc_width*2*coredynp.num_hthreads ;//PC and Next PC - /* pipe stage IF/ID */ - num_piperegs += coredynp.fetchW*(coredynp.instruction_length + coredynp.pc_width)*coredynp.num_hthreads;//PC is used to feed branch predictor in ID - /* pipe stage 1D/Renaming*/ - num_piperegs += coredynp.decodeW*(coredynp.instruction_length + coredynp.pc_width)*coredynp.num_hthreads;//PC is for branch exe in later stage. - /* pipe stage Renaming/wire_drive */ - num_piperegs += coredynp.decodeW*(coredynp.instruction_length + coredynp.pc_width); - /* pipe stage Renaming/IssueQ */ - num_piperegs += coredynp.issueW*(coredynp.instruction_length + coredynp.pc_width + 3*coredynp.phy_ireg_width)*coredynp.num_hthreads;//3*coredynp.phy_ireg_width means 2 sources and 1 dest - /* pipe stage IssueQ/Dispatch */ - num_piperegs += coredynp.issueW*(coredynp.instruction_length + 3 * coredynp.phy_ireg_width); - /* pipe stage Dispatch/EXE */ + } else { + /* assume 12 stage pipe stages and try to estimate bits per pipe stage */ + /*OOO: Fetch, decode, rename, IssueQ, dispatch, regread, EXE, MEM, WB, CM + */ - num_piperegs += coredynp.issueW*(3 * coredynp.phy_ireg_width + coredynp.pc_width + pow(2.0,opcode_length)/*+2*powers (2,reg_length)*/); - /* 2^opcode_length means the total decoded signal for the opcode*/ - num_piperegs += coredynp.issueW*(2*coredynp.int_data_width + pow(2.0,opcode_length)/*+2*powers (2,reg_length)*/); - /*2 source operands in EXE; Assume 2EXE stages* since we do not really distinguish OP*/ - num_piperegs += coredynp.issueW*(2*coredynp.int_data_width + pow(2.0,opcode_length)/*+2*powers (2,reg_length)*/); - /* pipe stage EXE/MEM, data need to be read/write, address*/ - num_piperegs += coredynp.issueW*(coredynp.int_data_width + coredynp.v_address_width + pow(2.0,opcode_length)/*+2*powers (2,reg_length)*/);//memory Opcode still need to be passed - /* pipe stage MEM/WB; result data, writeback regs */ - num_piperegs += coredynp.issueW*(coredynp.int_data_width + coredynp.phy_ireg_width /* powers (2,opcode_length) + (2,opcode_length)+2*powers (2,reg_length)*/); - /* pipe stage WB/CM ; result data, regs need to be updated, address for resolve memory ops in ROB's top*/ - num_piperegs += coredynp.commitW*(coredynp.int_data_width + coredynp.v_address_width + coredynp.phy_ireg_width/*+ powers (2,opcode_length)*2*powers (2,reg_length)*/)*coredynp.num_hthreads; -// if (multithreaded) -// { -// -// } - num_stages=12; + /* pipe stage 0/1F*/ + num_piperegs += + coredynp.pc_width * 2 * coredynp.num_hthreads; // PC and Next PC + /* pipe stage IF/ID */ + num_piperegs += + coredynp.fetchW * (coredynp.instruction_length + coredynp.pc_width) * + coredynp.num_hthreads; // PC is used to feed branch predictor in ID + /* pipe stage 1D/Renaming*/ + num_piperegs += + coredynp.decodeW * (coredynp.instruction_length + coredynp.pc_width) * + coredynp.num_hthreads; // PC is for branch exe in later stage. + /* pipe stage Renaming/wire_drive */ + num_piperegs += + coredynp.decodeW * (coredynp.instruction_length + coredynp.pc_width); + /* pipe stage Renaming/IssueQ */ + num_piperegs += coredynp.issueW * + (coredynp.instruction_length + coredynp.pc_width + + 3 * coredynp.phy_ireg_width) * + coredynp.num_hthreads; // 3*coredynp.phy_ireg_width means + // 2 sources and 1 dest + /* pipe stage IssueQ/Dispatch */ + num_piperegs += coredynp.issueW * (coredynp.instruction_length + + 3 * coredynp.phy_ireg_width); + /* pipe stage Dispatch/EXE */ - } + num_piperegs += coredynp.issueW * + (3 * coredynp.phy_ireg_width + coredynp.pc_width + + pow(2.0, opcode_length) /*+2*powers (2,reg_length)*/); + /* 2^opcode_length means the total decoded signal for the opcode*/ + num_piperegs += coredynp.issueW * + (2 * coredynp.int_data_width + + pow(2.0, opcode_length) /*+2*powers (2,reg_length)*/); + /*2 source operands in EXE; Assume 2EXE stages* since we do not really + * distinguish OP*/ + num_piperegs += coredynp.issueW * + (2 * coredynp.int_data_width + + pow(2.0, opcode_length) /*+2*powers (2,reg_length)*/); + /* pipe stage EXE/MEM, data need to be read/write, address*/ + num_piperegs += + coredynp.issueW * + (coredynp.int_data_width + coredynp.v_address_width + + pow(2.0, + opcode_length) /*+2*powers (2,reg_length)*/); // memory Opcode + // still need to + // be passed + /* pipe stage MEM/WB; result data, writeback regs */ + num_piperegs += + coredynp.issueW * (coredynp.int_data_width + coredynp.phy_ireg_width /* powers (2,opcode_length) + (2,opcode_length)+2*powers (2,reg_length)*/); + /* pipe stage WB/CM ; result data, regs need to be updated, address for + * resolve memory ops in ROB's top*/ + num_piperegs += + coredynp.commitW * + (coredynp.int_data_width + coredynp.v_address_width + coredynp.phy_ireg_width /*+ powers (2,opcode_length)*2*powers (2,reg_length)*/) * + coredynp.num_hthreads; + // if (multithreaded) + // { + // + // } + num_stages = 12; + } - /* assume 50% extra in control registers and interrupt registers (rule of thumb) */ - num_piperegs = num_piperegs * 1.5; - tot_stage_vector=num_piperegs; - per_stage_vector=tot_stage_vector/num_stages; + /* assume 50% extra in control registers and interrupt registers (rule of + * thumb) */ + num_piperegs = num_piperegs * 1.5; + tot_stage_vector = num_piperegs; + per_stage_vector = tot_stage_vector / num_stages; - if (coredynp.core_ty==Inorder) - { - if (coredynp.pipeline_stages>6) - num_piperegs= per_stage_vector*coredynp.pipeline_stages; - } - else//OOO - { - if (coredynp.pipeline_stages>12) - num_piperegs= per_stage_vector*coredynp.pipeline_stages; - } + if (coredynp.core_ty == Inorder) { + if (coredynp.pipeline_stages > 6) + num_piperegs = per_stage_vector * coredynp.pipeline_stages; + } else // OOO + { + if (coredynp.pipeline_stages > 12) + num_piperegs = per_stage_vector * coredynp.pipeline_stages; + } } - } -FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, enum FU_type fu_type_, double exClockRate) -:XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - fu_type(fu_type_) -{ - double area_t;//, leakage, gate_leakage; - double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); - clockRate = exClockRate;//coredynp.clockRate; - executionTime = coredynp.executionTime; - //cout<<"FU executionTime: "<<executionTime<<endl; - - //XML_interface=_XML_interface; - uca_org_t result2; - result2 = init_interface(&interface_ip); - if (XML->sys.Embedded) - { - if (fu_type == FPU) - { - num_fu=coredynp.num_fpus; - //area_t = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 - area_t = 4.47*1e6*(g_ip->F_sz_nm*g_ip->F_sz_nm/90.0/90.0);//this is um^2 The base number - //4.47 contains both VFP and NEON processing unit, VFP is about 40% and NEON is about 60% - if (g_ip->F_sz_nm>90) - area_t = 4.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 - leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - gate_leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - //energy = 0.3529/10*1e-9;//this is the energy(nJ) for a FP instruction in FPU usually it can have up to 20 cycles. -// base_energy = coredynp.core_ty==Inorder? 0: 89e-3*3; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch) -// base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); - base_energy = 0; - per_access_energy = 1.15/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per Hz energy(nJ) - //per_access_energy*=3; - //FPU power from Sandia's processor sizing tech report - FU_height=(18667*num_fu)*interface_ip.F_sz_um;//FPU from Sun's data - } - else if (fu_type == ALU) - { - num_fu=coredynp.num_alus; - //FIXME: The first area_t = is from updated McAPAT, the second is from our changes (conflict from base) - //area_t = 280*260*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl - area_t = 71.85*71.85*num_fu*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl - leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2; - leakage = 0; -// base_energy = coredynp.core_ty==Inorder? 0:89e-3; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch) -// base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); - base_energy = 0; - //per_access_energy = 1.15/3/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per cycle energy(nJ) - per_access_energy = 1.29/1e12/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0); - //per_access_energy*=3; - FU_height=(6222*num_fu)*interface_ip.F_sz_um;//integer ALU +FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, + InputParameter *interface_ip_, + const CoreDynParam &dyn_p_, + enum FU_type fu_type_, double exClockRate) + : XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + fu_type(fu_type_) { + double area_t; //, leakage, gate_leakage; + double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); + clockRate = exClockRate; // coredynp.clockRate; + executionTime = coredynp.executionTime; + // cout<<"FU executionTime: "<<executionTime<<endl; - } - else if (fu_type == MUL) - { - num_fu=coredynp.num_muls; - area_t = 280*260*3*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl - leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2; -// base_energy = coredynp.core_ty==Inorder? 0:89e-3*2; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch) -// base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); - base_energy = 0; - per_access_energy = 1.15*2/3/1e9/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2)/24;//0.00649*1e-9; //This is per cycle energy(nJ), coefficient based on Wattch (24 is the division ny latency: Syed) - //per_access_energy*=3; - FU_height=(9334*num_fu )*interface_ip.F_sz_um;//divider/mul from Sun's data - } - else - { - cout<<"Unknown Functional Unit Type"<<endl; - exit(0); - } - per_access_energy *=0.5;//According to ARM data embedded processor has much lower per acc energy - } /* if (XML->sys.Embedded) */ - else - { - if (fu_type == FPU) - { - num_fu=coredynp.num_fpus; - - /* - num_fu/=2; //2 DP FPUs combine to for a SP FPU - //area_t = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 - area_t = 8.47*1e6*(g_ip->F_sz_nm*g_ip->F_sz_nm/90.0/90.0);//this is um^2 - if (g_ip->F_sz_nm>90) - area_t = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 - leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - gate_leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - //energy = 0.3529/10*1e-9;//this is the energy(nJ) for a FP instruction in FPU usually it can have up to 20 cycles. - base_energy = coredynp.core_ty==Inorder? 0: 89e-3*3; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch) - base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); - per_access_energy = 1.15*3/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per op energy(nJ) - FU_height=(38667*num_fu)*interface_ip.F_sz_um;//FPU from Sun's data - */ - //area_t = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 - num_fu=num_fu/2; //2 DP FPUs combine to for a SP FPU - area_t = 8.47*1e6*(g_ip->F_sz_nm*g_ip->F_sz_nm/90.0/90.0);//this is um^2 - if (g_ip->F_sz_nm>90) - area_t = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 - leakage = 37e-3;//area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - gate_leakage = 0;//area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - //energy = 0.3529/10*1e-9;//this is the energy(nJ) for a FP instruction in FPU usually it can have up to 20 cycles. - base_energy = coredynp.core_ty==Inorder? 0: 89e-3*3; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch) + // XML_interface=_XML_interface; + uca_org_t result2; + result2 = init_interface(&interface_ip); + if (XML->sys.Embedded) { + if (fu_type == FPU) { + num_fu = coredynp.num_fpus; + // area_t = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is + // um^2 + area_t = 4.47 * 1e6 * + (g_ip->F_sz_nm * g_ip->F_sz_nm / 90.0 / + 90.0); // this is um^2 The base number + // 4.47 contains both VFP and NEON processing unit, VFP is about 40% and + // NEON is about 60% + if (g_ip->F_sz_nm > 90) + area_t = 4.47 * 1e6 * + g_tp.scaling_factor.logic_scaling_co_eff; // this is um^2 + leakage = area_t * (g_tp.scaling_factor.core_tx_density) * + cmos_Isub_leakage(5 * g_tp.min_w_nmos_, + 5 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, + 1, inv) * + g_tp.peri_global.Vdd / 2; // unit W + gate_leakage = area_t * (g_tp.scaling_factor.core_tx_density) * + cmos_Ig_leakage( + 5 * g_tp.min_w_nmos_, + 5 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, inv) * + g_tp.peri_global.Vdd / 2; // unit W + // energy = 0.3529/10*1e-9;//this is the energy(nJ) for a FP instruction + // in FPU usually it can have up to 20 cycles. + // base_energy = coredynp.core_ty==Inorder? 0: + // 89e-3*3; //W The base energy of ALU average numbers from Intel 4G and + // 773Mhz (Wattch) base_energy + //*=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); + base_energy = 0; + per_access_energy = + 1.15 / 1e9 / 4 / 1.3 / 1.3 * g_tp.peri_global.Vdd * + g_tp.peri_global.Vdd * + (g_ip->F_sz_nm / + 90.0); // g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; + // //This is per Hz energy(nJ) + // per_access_energy*=3; + // FPU power from Sandia's processor sizing tech report + FU_height = + (18667 * num_fu) * interface_ip.F_sz_um; // FPU from Sun's data + } else if (fu_type == ALU) { + num_fu = coredynp.num_alus; + // FIXME: The first area_t = is from updated McAPAT, the second is from + // our changes (conflict from base) area_t = + // 280*260*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + + // MUl + area_t = + 71.85 * 71.85 * num_fu * + g_tp.scaling_factor.logic_scaling_co_eff; // this is um^2 ALU + MUl + leakage = area_t * (g_tp.scaling_factor.core_tx_density) * + cmos_Isub_leakage(20 * g_tp.min_w_nmos_, + 20 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, + 1, inv) * + g_tp.peri_global.Vdd / 2; // unit W + gate_leakage = + area_t * (g_tp.scaling_factor.core_tx_density) * + cmos_Ig_leakage(20 * g_tp.min_w_nmos_, + 20 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, + inv) * + g_tp.peri_global.Vdd / 2; + leakage = 0; + // base_energy = coredynp.core_ty==Inorder? + // 0:89e-3; //W The base energy of ALU average numbers from Intel 4G and + // 773Mhz (Wattch) base_energy + //*=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); + base_energy = 0; + // per_access_energy + // = 1.15/3/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; + // //This is per cycle energy(nJ) + per_access_energy = 1.29 / 1e12 / 1.3 / 1.3 * g_tp.peri_global.Vdd * + g_tp.peri_global.Vdd * (g_ip->F_sz_nm / 90.0); + // per_access_energy*=3; + FU_height = (6222 * num_fu) * interface_ip.F_sz_um; // integer ALU - base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); + } else if (fu_type == MUL) { + num_fu = coredynp.num_muls; + area_t = + 280 * 260 * 3 * + g_tp.scaling_factor.logic_scaling_co_eff; // this is um^2 ALU + MUl + leakage = area_t * (g_tp.scaling_factor.core_tx_density) * + cmos_Isub_leakage(20 * g_tp.min_w_nmos_, + 20 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, + 1, inv) * + g_tp.peri_global.Vdd / 2; // unit W + gate_leakage = + area_t * (g_tp.scaling_factor.core_tx_density) * + cmos_Ig_leakage(20 * g_tp.min_w_nmos_, + 20 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, + inv) * + g_tp.peri_global.Vdd / 2; + // base_energy = coredynp.core_ty==Inorder? + // 0:89e-3*2; //W The base energy of ALU average numbers from Intel 4G and + // 773Mhz (Wattch) base_energy + //*=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); + base_energy = 0; + per_access_energy = + 1.15 * 2 / 3 / 1e9 / 1.3 / 1.3 * g_tp.peri_global.Vdd * + g_tp.peri_global.Vdd * + (g_ip->F_sz_nm / + 90.0); //(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2)/24;//0.00649*1e-9; + ////This is per cycle energy(nJ), coefficient based on Wattch + //(24 is the division ny latency: Syed) + // per_access_energy*=3; + FU_height = (9334 * num_fu) * + interface_ip.F_sz_um; // divider/mul from Sun's data + } else { + cout << "Unknown Functional Unit Type" << endl; + exit(0); + } + per_access_energy *= 0.5; // According to ARM data embedded processor has + // much lower per acc energy + } /* if (XML->sys.Embedded) */ + else { + if (fu_type == FPU) { + num_fu = coredynp.num_fpus; + /* + num_fu/=2; //2 DP FPUs combine to for a SP FPU + //area_t = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is + um^2 area_t = 8.47*1e6*(g_ip->F_sz_nm*g_ip->F_sz_nm/90.0/90.0);//this is + um^2 if (g_ip->F_sz_nm>90) area_t + = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 leakage + = area_t + *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, + 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, + inv)*g_tp.peri_global.Vdd/2;//unit W gate_leakage = area_t + *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, + 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, + inv)*g_tp.peri_global.Vdd/2;//unit W + //energy = 0.3529/10*1e-9;//this is the energy(nJ) for a FP instruction in + FPU usually it can have up to 20 cycles. base_energy = + coredynp.core_ty==Inorder? 0: 89e-3*3; //W The base energy of ALU average + numbers from Intel 4G and 773Mhz (Wattch) base_energy + *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); per_access_energy + = 1.15*3/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; + //This is per op energy(nJ) + FU_height=(38667*num_fu)*interface_ip.F_sz_um;//FPU from Sun's data + */ + // area_t = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is + // um^2 + num_fu = num_fu / 2; // 2 DP FPUs combine to for a SP FPU + area_t = 8.47 * 1e6 * + (g_ip->F_sz_nm * g_ip->F_sz_nm / 90.0 / 90.0); // this is um^2 + if (g_ip->F_sz_nm > 90) + area_t = 8.47 * 1e6 * + g_tp.scaling_factor.logic_scaling_co_eff; // this is um^2 + leakage = + 37e-3; // area_t + // *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, + // 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, + // inv)*g_tp.peri_global.Vdd/2;//unit W + gate_leakage = + 0; // area_t + // *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, + // 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, + // inv)*g_tp.peri_global.Vdd/2;//unit W + // energy = 0.3529/10*1e-9;//this is the energy(nJ) for a FP instruction + // in FPU usually it can have up to 20 cycles. + base_energy = + coredynp.core_ty == Inorder + ? 0 + : 89e-3 * 3; // W The base energy of ALU average numbers from + // Intel 4G and 773Mhz (Wattch) - //Base energy (if the pipeline is not clock gated) - //TODO: add a check for clockgating enable - base_energy=SP_BASE_POWER; + base_energy *= (g_tp.peri_global.Vdd * g_tp.peri_global.Vdd / 1.2 / 1.2); - //per_access_energy = 1.15*3/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per op energy(nJ) - per_access_energy = 3.9*14.91/1e12/1.08/1.08*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//;4.34 is scaling factor based on hardware measurements - //ALU instrucitons are also executed on FPUs so add 30% overhead for supporting ALU instrcutions - //per_access_energy = 1.3*per_access_energy; + // Base energy (if the pipeline is not clock gated) + // TODO: add a check for clockgating enable + base_energy = SP_BASE_POWER; + // per_access_energy + // = 1.15*3/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; + // //This is per op energy(nJ) + per_access_energy = + 3.9 * 14.91 / 1e12 / 1.08 / 1.08 * g_tp.peri_global.Vdd * + g_tp.peri_global.Vdd * + (g_ip->F_sz_nm / + 90.0); //;4.34 is scaling factor based on hardware measurements + // ALU instrucitons are also executed on FPUs so add 30% + // overhead for supporting ALU instrcutions per_access_energy + // = 1.3*per_access_energy; - //ALU instrucitons are also executed on FPUs so add 10% overhead for supporting ALU instrcutions - leakage = 1.1*leakage; - //cout<<"FPU Per access erngy: "<<per_access_energy/2; - //Divide per access energy by 2 so we have 4 DP units capapble of - //doing 8 SP operations - //per_access_energy = per_access_energy/2; - FU_height=(38667*num_fu)*interface_ip.F_sz_um;//FPU from Sun's data - per_access_energy*=2; - } - else if (fu_type == ALU) - { - num_fu=coredynp.num_alus; - //FIXME: The first area_t = is from updated McPAT. The second is from our McPAT changes. Fix after merge - //area_t = 280*260*2*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl - //leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - //gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2; - area_t = 71.85*71.85*num_fu*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl - //leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - //gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2; - //Following leakage numbers are based on Syntheis based power-estimation (SYED) - leakage = 2.58e-5; - gate_leakage = 0; - base_energy = coredynp.core_ty==Inorder? 0:89e-3; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch) - base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); - //per_access_energy = 1.15/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per cycle energy(nJ) - per_access_energy = 0.8*1.29/1e12/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0); - FU_height=(6222*num_fu)*interface_ip.F_sz_um;//integer ALU - per_access_energy*=2; - } - else if (fu_type == MUL) - { - num_fu=coredynp.num_muls; - area_t = 280*260*2*3*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl - //leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - leakage = 37e-3; - gate_leakage = 0;//area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2; - base_energy = coredynp.core_ty==Inorder? 0:89e-3*2; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch) - base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); - base_energy = SFU_BASE_POWER; - //SFU is modelled as a double preicison FPU - per_access_energy = 8*14.91/1e12/1.08/1.08*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//1.5 is scaling factor based on hardware measuremetns - FU_height=(9334*num_fu )*interface_ip.F_sz_um;//divider/mul from Sun's data - per_access_energy*=2; - } + // ALU instrucitons are also executed on FPUs so add 10% overhead for + // supporting ALU instrcutions + leakage = 1.1 * leakage; + // cout<<"FPU Per access erngy: "<<per_access_energy/2; + // Divide per access energy by 2 so we have 4 DP units capapble of + // doing 8 SP operations + // per_access_energy = per_access_energy/2; + FU_height = + (38667 * num_fu) * interface_ip.F_sz_um; // FPU from Sun's data + per_access_energy *= 2; + } else if (fu_type == ALU) { + num_fu = coredynp.num_alus; + // FIXME: The first area_t = is from updated McPAT. The second is from our + // McPAT changes. Fix after merge area_t = + // 280*260*2*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + + // MUl leakage = area_t + // *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, + // 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, + // inv)*g_tp.peri_global.Vdd/2;//unit W gate_leakage = + // area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, + // 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, + // inv)*g_tp.peri_global.Vdd/2; + area_t = + 71.85 * 71.85 * num_fu * + g_tp.scaling_factor.logic_scaling_co_eff; // this is um^2 ALU + MUl + // leakage = area_t + // *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, + // 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, + // inv)*g_tp.peri_global.Vdd/2;//unit W gate_leakage = + // area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, + // 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, + // inv)*g_tp.peri_global.Vdd/2; Following leakage numbers are based on + // Syntheis based power-estimation (SYED) + leakage = 2.58e-5; + gate_leakage = 0; + base_energy = coredynp.core_ty == Inorder + ? 0 + : 89e-3; // W The base energy of ALU average numbers + // from Intel 4G and 773Mhz (Wattch) + base_energy *= (g_tp.peri_global.Vdd * g_tp.peri_global.Vdd / 1.2 / 1.2); + // per_access_energy + // = 1.15/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; + // //This is per cycle energy(nJ) + per_access_energy = 0.8 * 1.29 / 1e12 / 1.3 / 1.3 * g_tp.peri_global.Vdd * + g_tp.peri_global.Vdd * (g_ip->F_sz_nm / 90.0); + FU_height = (6222 * num_fu) * interface_ip.F_sz_um; // integer ALU + per_access_energy *= 2; + } else if (fu_type == MUL) { + num_fu = coredynp.num_muls; + area_t = + 280 * 260 * 2 * 3 * + g_tp.scaling_factor.logic_scaling_co_eff; // this is um^2 ALU + MUl + // leakage = area_t + // *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, + // 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, + // inv)*g_tp.peri_global.Vdd/2;//unit W + leakage = 37e-3; + gate_leakage = + 0; // area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, + // 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, + // inv)*g_tp.peri_global.Vdd/2; + base_energy = + coredynp.core_ty == Inorder + ? 0 + : 89e-3 * 2; // W The base energy of ALU average numbers from + // Intel 4G and 773Mhz (Wattch) + base_energy *= (g_tp.peri_global.Vdd * g_tp.peri_global.Vdd / 1.2 / 1.2); + base_energy = SFU_BASE_POWER; + // SFU is modelled as a double preicison FPU + per_access_energy = + 8 * 14.91 / 1e12 / 1.08 / 1.08 * g_tp.peri_global.Vdd * + g_tp.peri_global.Vdd * + (g_ip->F_sz_nm / + 90.0); // 1.5 is scaling factor based on hardware measuremetns + FU_height = (9334 * num_fu) * + interface_ip.F_sz_um; // divider/mul from Sun's data + per_access_energy *= 2; + } - else - { - cout<<"Unknown Functional Unit Type"<<endl; - exit(0); - } - } - //IEXEU, simple ALU and FPU - // double C_ALU, C_EXEU, C_FPU; //Lum Equivalent capacitance of IEXEU and FPU. Based on Intel and Sun 90nm process fabracation. - // - // C_ALU = 0.025e-9;//F - // C_EXEU = 0.05e-9; //F - // C_FPU = 0.35e-9;//F - area.set_area(area_t*num_fu); - leakage *= num_fu; - gate_leakage *=num_fu; - double macro_layout_overhead = g_tp.macro_layout_overhead; -// if (!XML->sys.Embedded) - area.set_area(area.get_area()*macro_layout_overhead); + else { + cout << "Unknown Functional Unit Type" << endl; + exit(0); + } + } + // IEXEU, simple ALU and FPU + // double C_ALU, C_EXEU, C_FPU; //Lum Equivalent capacitance of IEXEU and + // FPU. Based on Intel and Sun 90nm process fabracation. + // + // C_ALU = 0.025e-9;//F + // C_EXEU = 0.05e-9; //F + // C_FPU = 0.35e-9;//F + area.set_area(area_t * num_fu); + leakage *= num_fu; + gate_leakage *= num_fu; + double macro_layout_overhead = g_tp.macro_layout_overhead; + // if (!XML->sys.Embedded) + area.set_area(area.get_area() * macro_layout_overhead); } -void FunctionalUnit::computeEnergy(bool is_tdp) -{ - - executionTime=XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed - double pppm_t[4] = {1,1,1,1}; - double FU_duty_cycle; - if (is_tdp) - { - - - set_pppm(pppm_t, 2, 2, 2, 2);//2 means two source operands needs to be passed for each int instruction. - if (fu_type == FPU) - { - stats_t.readAc.access = num_fu; - tdp_stats = stats_t; - //Syed: FPU power numbers are already average - //so activity factor is already accounted for - FU_duty_cycle= coredynp.FPU_duty_cycle; - } - else if (fu_type == ALU) - { - stats_t.readAc.access = 1*num_fu; - tdp_stats = stats_t; - FU_duty_cycle = coredynp.ALU_duty_cycle; - } - else if (fu_type == MUL) - { - stats_t.readAc.access = num_fu; - tdp_stats = stats_t; - FU_duty_cycle = coredynp.MUL_duty_cycle; - } - - //power.readOp.dynamic = base_energy/clockRate + energy*stats_t.readAc.access; - power.readOp.dynamic = per_access_energy*stats_t.readAc.access + base_energy/clockRate; - double sckRation = g_tp.sckt_co_eff; - power.readOp.dynamic *= sckRation*FU_duty_cycle; - power.writeOp.dynamic *= sckRation; - power.searchOp.dynamic *= sckRation; - - power.readOp.leakage = leakage; - power.readOp.gate_leakage = gate_leakage; - double long_channel_device_reduction = longer_channel_device_reduction(Core_device, coredynp.core_ty); - power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction; +void FunctionalUnit::computeEnergy(bool is_tdp) { + executionTime = + XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); // Syed + double pppm_t[4] = {1, 1, 1, 1}; + double FU_duty_cycle; + if (is_tdp) { + set_pppm(pppm_t, 2, 2, 2, 2); // 2 means two source operands needs to be + // passed for each int instruction. + if (fu_type == FPU) { + stats_t.readAc.access = num_fu; + tdp_stats = stats_t; + // Syed: FPU power numbers are already average + // so activity factor is already accounted for + FU_duty_cycle = coredynp.FPU_duty_cycle; + } else if (fu_type == ALU) { + stats_t.readAc.access = 1 * num_fu; + tdp_stats = stats_t; + FU_duty_cycle = coredynp.ALU_duty_cycle; + } else if (fu_type == MUL) { + stats_t.readAc.access = num_fu; + tdp_stats = stats_t; + FU_duty_cycle = coredynp.MUL_duty_cycle; + } - } - else - { - if (fu_type == FPU) - { - //Each access activates an equililant of a double-precision unit - //so divide accesses into half - stats_t.readAc.access = XML->sys.core[ithCore].fpu_accesses; - rtp_stats = stats_t; - //cout<<"FPU: --accesses "<<stats_t.readAc.access <<endl; + // power.readOp.dynamic = base_energy/clockRate + + // energy*stats_t.readAc.access; + power.readOp.dynamic = + per_access_energy * stats_t.readAc.access + base_energy / clockRate; + double sckRation = g_tp.sckt_co_eff; + power.readOp.dynamic *= sckRation * FU_duty_cycle; + power.writeOp.dynamic *= sckRation; + power.searchOp.dynamic *= sckRation; - } - else if (fu_type == ALU) - { - stats_t.readAc.access = XML->sys.core[ithCore].ialu_accesses; - rtp_stats = stats_t; - //cout<<"ALU: --accesses "<<stats_t.readAc.access <<endl; - } - else if (fu_type == MUL) - { - stats_t.readAc.access = XML->sys.core[ithCore].mul_accesses; - rtp_stats = stats_t; - //cout<<"MUL: --accesses "<<stats_t.readAc.access <<endl; - } + power.readOp.leakage = leakage; + power.readOp.gate_leakage = gate_leakage; + double long_channel_device_reduction = + longer_channel_device_reduction(Core_device, coredynp.core_ty); + power.readOp.longer_channel_leakage = + power.readOp.leakage * long_channel_device_reduction; - //rt_power.readOp.dynamic = base_energy*executionTime + energy*stats_t.readAc.access; - - if(fu_type == ALU){ - rt_power.readOp.dynamic = per_access_energy*stats_t.readAc.access + base_energy*executionTime; - } - else{ - rt_power.readOp.dynamic = per_access_energy*stats_t.readAc.access; - } + } else { + if (fu_type == FPU) { + // Each access activates an equililant of a double-precision unit + // so divide accesses into half + stats_t.readAc.access = XML->sys.core[ithCore].fpu_accesses; + rtp_stats = stats_t; + // cout<<"FPU: --accesses "<<stats_t.readAc.access <<endl; - double sckRation = g_tp.sckt_co_eff; - rt_power.readOp.dynamic *= sckRation; - rt_power.writeOp.dynamic *= sckRation; - rt_power.searchOp.dynamic *= sckRation; - //cout<<"Power: "<<rt_power.readOp.dynamic<<endl; - if(fu_type == FPU){ - rt_power.readOp.dynamic += base_energy*executionTime*(32-XML->sys.core[ithCore].sp_average_active_lanes); - } - if(fu_type == MUL){ - if(XML->sys.core[ithCore].sfu_average_active_lanes>=1) - rt_power.readOp.dynamic += base_energy*executionTime*(32-XML->sys.core[ithCore].sfu_average_active_lanes); - } + } else if (fu_type == ALU) { + stats_t.readAc.access = XML->sys.core[ithCore].ialu_accesses; + rtp_stats = stats_t; + // cout<<"ALU: --accesses "<<stats_t.readAc.access <<endl; + } else if (fu_type == MUL) { + stats_t.readAc.access = XML->sys.core[ithCore].mul_accesses; + rtp_stats = stats_t; + // cout<<"MUL: --accesses "<<stats_t.readAc.access <<endl; + } - } /* else */ + // rt_power.readOp.dynamic = base_energy*executionTime + + // energy*stats_t.readAc.access; + if (fu_type == ALU) { + rt_power.readOp.dynamic = per_access_energy * stats_t.readAc.access + + base_energy * executionTime; + } else { + rt_power.readOp.dynamic = per_access_energy * stats_t.readAc.access; + } + double sckRation = g_tp.sckt_co_eff; + rt_power.readOp.dynamic *= sckRation; + rt_power.writeOp.dynamic *= sckRation; + rt_power.searchOp.dynamic *= sckRation; + // cout<<"Power: "<<rt_power.readOp.dynamic<<endl; + if (fu_type == FPU) { + rt_power.readOp.dynamic += + base_energy * executionTime * + (32 - XML->sys.core[ithCore].sp_average_active_lanes); + } + if (fu_type == MUL) { + if (XML->sys.core[ithCore].sfu_average_active_lanes >= 1) + rt_power.readOp.dynamic += + base_energy * executionTime * + (32 - XML->sys.core[ithCore].sfu_average_active_lanes); + } + } /* else */ } -void FunctionalUnit::displayEnergy(uint32_t indent,int plevel,bool is_tdp) -{ - string indent_str(indent, ' '); - string indent_str_next(indent+2, ' '); - bool long_channel = XML->sys.longer_channel_device; - -// cout << indent_str_next << "Results Broadcast Bus Area = " << bypass->area.get_area() *1e-6 << " mm^2" << endl; - if (is_tdp) - { - if (fu_type == FPU) - { - cout << indent_str << "Floating Point Units (FPUs) (Count: "<< coredynp.num_fpus <<" ):" << endl; - cout << indent_str_next << "Area = " << area.get_area()*1e-6 << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Peak Energy = " << power.readOp.dynamic << " J" << endl; - -// cout << indent_str_next << "Subthreshold Leakage = " << power.readOp.leakage << " W" << endl; - //cout <<"clock: "<<clockRate<<endl; - cout << indent_str_next<< "Subthreshold Leakage = " - << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <<endl; - } - else if (fu_type == ALU) - { - cout << indent_str << "Integer ALUs (Count: "<< coredynp.num_alus <<" ):" << endl; - cout << indent_str_next << "Area = " << area.get_area()*1e-6 << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << power.readOp.dynamic*clockRate << " W" << endl; -// cout << indent_str_next << "Subthreshold Leakage = " << power.readOp.leakage << " W" << endl; - cout << indent_str_next<< "Subthreshold Leakage = " - << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <<endl; - } - else if (fu_type == MUL) - { - cout << indent_str << "Complex ALUs (Mul/Div) (Count: "<< coredynp.num_muls <<" ):" << endl; - cout << indent_str_next << "Area = " << area.get_area()*1e-6 << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << power.readOp.dynamic*clockRate << " W" << endl; -// cout << indent_str_next << "Subthreshold Leakage = " << power.readOp.leakage << " W" << endl; - cout << indent_str_next<< "Subthreshold Leakage = " - << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <<endl; +void FunctionalUnit::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { + string indent_str(indent, ' '); + string indent_str_next(indent + 2, ' '); + bool long_channel = XML->sys.longer_channel_device; - } + // cout << indent_str_next << "Results Broadcast Bus Area = " << + // bypass->area.get_area() *1e-6 << " mm^2" << endl; + if (is_tdp) { + if (fu_type == FPU) { + cout << indent_str + << "Floating Point Units (FPUs) (Count: " << coredynp.num_fpus + << " ):" << endl; + cout << indent_str_next << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next + << "Peak Dynamic = " << power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Peak Energy = " << power.readOp.dynamic + << " J" << endl; - } - else - { - } + // cout << indent_str_next << "Subthreshold Leakage + //= " << power.readOp.leakage << " W" << endl; cout <<"clock: + // "<<clockRate<<endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage + << " W" << endl; + cout << indent_str_next + << "Runtime Dynamic = " << rt_power.readOp.dynamic / executionTime + << " W" << endl; + cout << endl; + } else if (fu_type == ALU) { + cout << indent_str << "Integer ALUs (Count: " << coredynp.num_alus + << " ):" << endl; + cout << indent_str_next << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next + << "Peak Dynamic = " << power.readOp.dynamic * clockRate << " W" + << endl; + // cout << indent_str_next << "Subthreshold Leakage + //= " << power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage + << " W" << endl; + cout << indent_str_next + << "Runtime Dynamic = " << rt_power.readOp.dynamic / executionTime + << " W" << endl; + cout << endl; + } else if (fu_type == MUL) { + cout << indent_str + << "Complex ALUs (Mul/Div) (Count: " << coredynp.num_muls + << " ):" << endl; + cout << indent_str_next << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next + << "Peak Dynamic = " << power.readOp.dynamic * clockRate << " W" + << endl; + // cout << indent_str_next << "Subthreshold Leakage + //= " << power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage + << " W" << endl; + cout << indent_str_next + << "Runtime Dynamic = " << rt_power.readOp.dynamic / executionTime + << " W" << endl; + cout << endl; + } + } else { + } } -void FunctionalUnit::leakage_feedback(double temperature) -{ +void FunctionalUnit::leakage_feedback(double temperature) { // Update the temperature and initialize the global interfaces. - interface_ip.temp = (unsigned int)round(temperature/10.0)*10; + interface_ip.temp = (unsigned int)round(temperature / 10.0) * 10; - uca_org_t init_result = init_interface(&interface_ip); // init_result is dummy + uca_org_t init_result = + init_interface(&interface_ip); // init_result is dummy // This is part of FunctionalUnit() double area_t, leakage, gate_leakage; double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); - if (fu_type == FPU) - { - area_t = 4.47*1e6*(g_ip->F_sz_nm*g_ip->F_sz_nm/90.0/90.0);//this is um^2 The base number - if (g_ip->F_sz_nm>90) - area_t = 4.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 - leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - gate_leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - } - else if (fu_type == ALU) - { - area_t = 280*260*2*num_fu*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl - leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2; - } - else if (fu_type == MUL) - { - area_t = 280*260*2*3*num_fu*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl - leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W - gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2; - } - else - { - cout<<"Unknown Functional Unit Type"<<endl; + if (fu_type == FPU) { + area_t = 4.47 * 1e6 * + (g_ip->F_sz_nm * g_ip->F_sz_nm / 90.0 / + 90.0); // this is um^2 The base number + if (g_ip->F_sz_nm > 90) + area_t = 4.47 * 1e6 * + g_tp.scaling_factor.logic_scaling_co_eff; // this is um^2 + leakage = area_t * (g_tp.scaling_factor.core_tx_density) * + cmos_Isub_leakage(5 * g_tp.min_w_nmos_, + 5 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, + inv) * + g_tp.peri_global.Vdd / 2; // unit W + gate_leakage = + area_t * (g_tp.scaling_factor.core_tx_density) * + cmos_Ig_leakage(5 * g_tp.min_w_nmos_, + 5 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, inv) * + g_tp.peri_global.Vdd / 2; // unit W + } else if (fu_type == ALU) { + area_t = + 280 * 260 * 2 * num_fu * + g_tp.scaling_factor.logic_scaling_co_eff; // this is um^2 ALU + MUl + leakage = area_t * (g_tp.scaling_factor.core_tx_density) * + cmos_Isub_leakage(20 * g_tp.min_w_nmos_, + 20 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, + 1, inv) * + g_tp.peri_global.Vdd / 2; // unit W + gate_leakage = + area_t * (g_tp.scaling_factor.core_tx_density) * + cmos_Ig_leakage(20 * g_tp.min_w_nmos_, + 20 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, inv) * + g_tp.peri_global.Vdd / 2; + } else if (fu_type == MUL) { + area_t = + 280 * 260 * 2 * 3 * num_fu * + g_tp.scaling_factor.logic_scaling_co_eff; // this is um^2 ALU + MUl + leakage = area_t * (g_tp.scaling_factor.core_tx_density) * + cmos_Isub_leakage(20 * g_tp.min_w_nmos_, + 20 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, + 1, inv) * + g_tp.peri_global.Vdd / 2; // unit W + gate_leakage = + area_t * (g_tp.scaling_factor.core_tx_density) * + cmos_Ig_leakage(20 * g_tp.min_w_nmos_, + 20 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, inv) * + g_tp.peri_global.Vdd / 2; + } else { + cout << "Unknown Functional Unit Type" << endl; exit(1); } - power.readOp.leakage = leakage*num_fu; - power.readOp.gate_leakage = gate_leakage*num_fu; - power.readOp.longer_channel_leakage = longer_channel_device_reduction(Core_device, coredynp.core_ty); + power.readOp.leakage = leakage * num_fu; + power.readOp.gate_leakage = gate_leakage * num_fu; + power.readOp.longer_channel_leakage = + longer_channel_device_reduction(Core_device, coredynp.core_ty); } -UndiffCore::UndiffCore(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_, bool exist_, bool embedded_) -:XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - core_ty(coredynp.core_ty), - embedded(XML->sys.Embedded), - pipeline_stage(coredynp.pipeline_stages), - num_hthreads(coredynp.num_hthreads), - issue_width(coredynp.issueW), - exist(exist_) +UndiffCore::UndiffCore(ParseXML *XML_interface, int ithCore_, + InputParameter *interface_ip_, + const CoreDynParam &dyn_p_, bool exist_, bool embedded_) + : XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + core_ty(coredynp.core_ty), + embedded(XML->sys.Embedded), + pipeline_stage(coredynp.pipeline_stages), + num_hthreads(coredynp.num_hthreads), + issue_width(coredynp.issueW), + exist(exist_) // is_default(_is_default) { - if (!exist) return; - double undifferentiated_core=0; - double core_tx_density=0; - double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); - double undifferentiated_core_coe; - //XML_interface=_XML_interface; - uca_org_t result2; - result2 = init_interface(&interface_ip); - - //Compute undifferentiated core area at 90nm. - if (embedded==false) - { - //Based on the results of polynomial/log curve fitting based on undifferentiated core of Niagara, Niagara2, Merom, Penyrn, Prescott, Opteron die measurements - if (core_ty==OOO) - { - //undifferentiated_core = (0.0764*pipeline_stage*pipeline_stage -2.3685*pipeline_stage + 10.405);//OOO - undifferentiated_core = (3.57*log(pipeline_stage)-1.2643)>0?(3.57*log(pipeline_stage)-1.2643):0; - } - else if (core_ty==Inorder) - { - //undifferentiated_core = (0.1238*pipeline_stage + 7.2572)*0.9;//inorder - undifferentiated_core = (-2.19*log(pipeline_stage)+6.55)>0?(-2.19*log(pipeline_stage)+6.55):0; - } - else - { - cout<<"invalid core type"<<endl; - exit(0); - } - undifferentiated_core *= (1+ logtwo(num_hthreads)* 0.0716); - } - else - { - //Based on the results in paper "parametrized processor models" Sandia Labs - if (XML->sys.opt_clockrate) - undifferentiated_core_coe = 0.05; - else - undifferentiated_core_coe = 0; - undifferentiated_core = (0.4109* pipeline_stage - 0.776)*undifferentiated_core_coe; - undifferentiated_core *= (1+ logtwo(num_hthreads)* 0.0426); - } - - undifferentiated_core *= g_tp.scaling_factor.logic_scaling_co_eff*1e6;//change from mm^2 to um^2 - core_tx_density = g_tp.scaling_factor.core_tx_density; - //undifferentiated_core = 3*1e6; - //undifferentiated_core *= g_tp.scaling_factor.logic_scaling_co_eff;//(g_ip->F_sz_um*g_ip->F_sz_um/0.09/0.09)*; - power.readOp.leakage = undifferentiated_core*(core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd;//unit W - power.readOp.gate_leakage = undifferentiated_core*(core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd; - - double long_channel_device_reduction = longer_channel_device_reduction(Core_device, coredynp.core_ty); - power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction; - area.set_area(undifferentiated_core); - - scktRatio = g_tp.sckt_co_eff; - power.readOp.dynamic *= scktRatio; - power.writeOp.dynamic *= scktRatio; - power.searchOp.dynamic *= scktRatio; - macro_PR_overhead = g_tp.macro_layout_overhead; - area.set_area(area.get_area()*macro_PR_overhead); - + if (!exist) return; + double undifferentiated_core = 0; + double core_tx_density = 0; + double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); + double undifferentiated_core_coe; + // XML_interface=_XML_interface; + uca_org_t result2; + result2 = init_interface(&interface_ip); + // Compute undifferentiated core area at 90nm. + if (embedded == false) { + // Based on the results of polynomial/log curve fitting based on + // undifferentiated core of Niagara, Niagara2, Merom, Penyrn, Prescott, + // Opteron die measurements + if (core_ty == OOO) { + // undifferentiated_core = (0.0764*pipeline_stage*pipeline_stage + // -2.3685*pipeline_stage + 10.405);//OOO + undifferentiated_core = (3.57 * log(pipeline_stage) - 1.2643) > 0 + ? (3.57 * log(pipeline_stage) - 1.2643) + : 0; + } else if (core_ty == Inorder) { + // undifferentiated_core = (0.1238*pipeline_stage + 7.2572)*0.9;//inorder + undifferentiated_core = (-2.19 * log(pipeline_stage) + 6.55) > 0 + ? (-2.19 * log(pipeline_stage) + 6.55) + : 0; + } else { + cout << "invalid core type" << endl; + exit(0); + } + undifferentiated_core *= (1 + logtwo(num_hthreads) * 0.0716); + } else { + // Based on the results in paper "parametrized processor models" Sandia Labs + if (XML->sys.opt_clockrate) + undifferentiated_core_coe = 0.05; + else + undifferentiated_core_coe = 0; + undifferentiated_core = + (0.4109 * pipeline_stage - 0.776) * undifferentiated_core_coe; + undifferentiated_core *= (1 + logtwo(num_hthreads) * 0.0426); + } -// double vt=g_tp.peri_global.Vth; -// double velocity_index=1.1; -// double c_in=gate_C(g_tp.min_w_nmos_, g_tp.min_w_nmos_*pmos_to_nmos_sizing_r , 0.0, false); -// double c_out= drain_C_(g_tp.min_w_nmos_, NCH, 2, 1, g_tp.cell_h_def, false) + drain_C_(g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, PCH, 1, 1, g_tp.cell_h_def, false) + c_in; -// double w_nmos=g_tp.min_w_nmos_; -// double w_pmos=g_tp.min_w_nmos_*pmos_to_nmos_sizing_r; -// double i_on_n=1.0; -// double i_on_p=1.0; -// double i_on_n_in=1.0; -// double i_on_p_in=1; -// double vdd=g_tp.peri_global.Vdd; + undifferentiated_core *= g_tp.scaling_factor.logic_scaling_co_eff * + 1e6; // change from mm^2 to um^2 + core_tx_density = g_tp.scaling_factor.core_tx_density; + // undifferentiated_core = 3*1e6; + // undifferentiated_core *= + // g_tp.scaling_factor.logic_scaling_co_eff;//(g_ip->F_sz_um*g_ip->F_sz_um/0.09/0.09)*; + power.readOp.leakage = + undifferentiated_core * + (core_tx_density)*cmos_Isub_leakage( + 5 * g_tp.min_w_nmos_, 5 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, + inv) * + g_tp.peri_global.Vdd; // unit W + power.readOp.gate_leakage = + undifferentiated_core * + (core_tx_density)*cmos_Ig_leakage( + 5 * g_tp.min_w_nmos_, 5 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, + inv) * + g_tp.peri_global.Vdd; -// power.readOp.sc=shortcircuit_simple(vt, velocity_index, c_in, c_out, w_nmos,w_pmos, i_on_n, i_on_p,i_on_n_in, i_on_p_in, vdd); -// power.readOp.dynamic=c_out*vdd*vdd/2; + double long_channel_device_reduction = + longer_channel_device_reduction(Core_device, coredynp.core_ty); + power.readOp.longer_channel_leakage = + power.readOp.leakage * long_channel_device_reduction; + area.set_area(undifferentiated_core); -// cout<<power.readOp.dynamic << "dynamic" <<endl; -// cout<<power.readOp.sc << "sc" << endl; + scktRatio = g_tp.sckt_co_eff; + power.readOp.dynamic *= scktRatio; + power.writeOp.dynamic *= scktRatio; + power.searchOp.dynamic *= scktRatio; + macro_PR_overhead = g_tp.macro_layout_overhead; + area.set_area(area.get_area() * macro_PR_overhead); -// power.readOp.sc=shortcircuit(vt, velocity_index, c_in, c_out, w_nmos,w_pmos, i_on_n, i_on_p,i_on_n_in, i_on_p_in, vdd); -// power.readOp.dynamic=c_out*vdd*vdd/2; -// -// cout<<power.readOp.dynamic << "dynamic" <<endl; -// cout<<power.readOp.sc << "sc" << endl; + // double vt=g_tp.peri_global.Vth; + // double velocity_index=1.1; + // double c_in=gate_C(g_tp.min_w_nmos_, + // g_tp.min_w_nmos_*pmos_to_nmos_sizing_r , 0.0, false); double + // c_out= drain_C_(g_tp.min_w_nmos_, NCH, 2, 1, g_tp.cell_h_def, false) + + // drain_C_(g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, PCH, 1, 1, + // g_tp.cell_h_def, false) + c_in; double w_nmos=g_tp.min_w_nmos_; + // double w_pmos=g_tp.min_w_nmos_*pmos_to_nmos_sizing_r; double + // i_on_n=1.0; double + // i_on_p=1.0; double i_on_n_in=1.0; double + // i_on_p_in=1; double vdd=g_tp.peri_global.Vdd; + // power.readOp.sc=shortcircuit_simple(vt, velocity_index, c_in, + // c_out, w_nmos,w_pmos, i_on_n, i_on_p,i_on_n_in, i_on_p_in, vdd); + // power.readOp.dynamic=c_out*vdd*vdd/2; + // cout<<power.readOp.dynamic << "dynamic" <<endl; + // cout<<power.readOp.sc << "sc" << endl; + // power.readOp.sc=shortcircuit(vt, velocity_index, c_in, c_out, + // w_nmos,w_pmos, i_on_n, i_on_p,i_on_n_in, i_on_p_in, vdd); + // power.readOp.dynamic=c_out*vdd*vdd/2; + // + // cout<<power.readOp.dynamic << "dynamic" <<endl; + // cout<<power.readOp.sc << "sc" << endl; } +void UndiffCore::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { + string indent_str(indent, ' '); + string indent_str_next(indent + 2, ' '); + bool long_channel = XML->sys.longer_channel_device; -void UndiffCore::displayEnergy(uint32_t indent,int plevel,bool is_tdp) -{ - string indent_str(indent, ' '); - string indent_str_next(indent+2, ' '); - bool long_channel = XML->sys.longer_channel_device; - - if (is_tdp) - { - cout << indent_str << "UndiffCore:" << endl; - cout << indent_str_next << "Area = " << area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << power.readOp.dynamic*clockRate << " W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << power.readOp.leakage <<" W" << endl; - cout << indent_str_next<< "Subthreshold Leakage = " - << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; - //cout << indent_str_next << "Runtime Dynamic = " << rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <<endl; - } - else - { - cout << indent_str << "UndiffCore:" << endl; - cout << indent_str_next << "Area = " << area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " << power.readOp.leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; - //cout << indent_str_next << "Runtime Dynamic = " << rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <<endl; - } - + if (is_tdp) { + cout << indent_str << "UndiffCore:" << endl; + cout << indent_str_next << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next + << "Peak Dynamic = " << power.readOp.dynamic * clockRate << " W" + << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // power.readOp.leakage <<" W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage + << " W" << endl; + // cout << indent_str_next << "Runtime Dynamic = " << + // rt_power.readOp.dynamic/executionTime << " W" << endl; + cout << endl; + } else { + cout << indent_str << "UndiffCore:" << endl; + cout << indent_str_next << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next + << "Peak Dynamic = " << power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " << power.readOp.leakage + << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage + << " W" << endl; + // cout << indent_str_next << "Runtime Dynamic = " << + // rt_power.readOp.dynamic/executionTime << " W" << endl; + cout << endl; + } } -inst_decoder::inst_decoder( - bool _is_default, - const InputParameter *configure_interface, - int opcode_length_, - int num_decoders_, - bool x86_, - enum Device_ty device_ty_, - enum Core_type core_ty_) -:is_default(_is_default), - opcode_length(opcode_length_), - num_decoders(num_decoders_), - x86(x86_), - device_ty(device_ty_), - core_ty(core_ty_) - { - /* - * Instruction decoder is different from n to 2^n decoders - * that are commonly used in row decoders in memory arrays. - * The RISC instruction decoder is typically a very simple device. - * We can decode an instruction by simply - * separating the machine word into small parts using wire slices - * The RISC instruction decoder can be approximate by the n to 2^n decoders, - * although this approximation usually underestimate power since each decoded - * instruction normally has more than 1 active signal. - * - * However, decoding a CISC instruction word is much more difficult - * than the RISC case. A CISC decoder is typically set up as a state machine. - * The machine reads the opcode field to determine - * what type of instruction it is, - * and where the other data values are. - * The instruction word is read in piece by piece, - * and decisions are made at each stage as to - * how the remainder of the instruction word will be read. - * (sequencer and ROM are usually needed) - * An x86 decoder can be even more complex since - * it involve both decoding instructions into u-ops and - * merge u-ops when doing micro-ops fusion. - */ - bool is_dram=false; - double pmos_to_nmos_sizing_r; - double load_nmos_width, load_pmos_width; - double C_driver_load, R_wire_load; - Area cell; - - l_ip=*configure_interface; - local_result = init_interface(&l_ip); - cell.h =g_tp.cell_h_def; - cell.w =g_tp.cell_h_def; +inst_decoder::inst_decoder(bool _is_default, + const InputParameter *configure_interface, + int opcode_length_, int num_decoders_, bool x86_, + enum Device_ty device_ty_, enum Core_type core_ty_) + : is_default(_is_default), + opcode_length(opcode_length_), + num_decoders(num_decoders_), + x86(x86_), + device_ty(device_ty_), + core_ty(core_ty_) { + /* + * Instruction decoder is different from n to 2^n decoders + * that are commonly used in row decoders in memory arrays. + * The RISC instruction decoder is typically a very simple device. + * We can decode an instruction by simply + * separating the machine word into small parts using wire slices + * The RISC instruction decoder can be approximate by the n to 2^n decoders, + * although this approximation usually underestimate power since each decoded + * instruction normally has more than 1 active signal. + * + * However, decoding a CISC instruction word is much more difficult + * than the RISC case. A CISC decoder is typically set up as a state machine. + * The machine reads the opcode field to determine + * what type of instruction it is, + * and where the other data values are. + * The instruction word is read in piece by piece, + * and decisions are made at each stage as to + * how the remainder of the instruction word will be read. + * (sequencer and ROM are usually needed) + * An x86 decoder can be even more complex since + * it involve both decoding instructions into u-ops and + * merge u-ops when doing micro-ops fusion. + */ + bool is_dram = false; + double pmos_to_nmos_sizing_r; + double load_nmos_width, load_pmos_width; + double C_driver_load, R_wire_load; + Area cell; - num_decoder_segments = (int)ceil(opcode_length/18.0); - if (opcode_length > 18) opcode_length = 18; - num_decoded_signals= (int)pow(2.0,opcode_length); - pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); - load_nmos_width=g_tp.max_w_nmos_ /2; - load_pmos_width= g_tp.max_w_nmos_ * pmos_to_nmos_sizing_r; - C_driver_load = 1024*gate_C(load_nmos_width + load_pmos_width, 0, is_dram); //TODO: this number 1024 needs to be revisited - R_wire_load = 3000*l_ip.F_sz_um * g_tp.wire_outside_mat.R_per_um; + l_ip = *configure_interface; + local_result = init_interface(&l_ip); + cell.h = g_tp.cell_h_def; + cell.w = g_tp.cell_h_def; - final_dec = new Decoder( - num_decoded_signals, - false, - C_driver_load, - R_wire_load, - false/*is_fa*/, - false/*is_dram*/, - false/*wl_tr*/, //to use peri device - cell); + num_decoder_segments = (int)ceil(opcode_length / 18.0); + if (opcode_length > 18) opcode_length = 18; + num_decoded_signals = (int)pow(2.0, opcode_length); + pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); + load_nmos_width = g_tp.max_w_nmos_ / 2; + load_pmos_width = g_tp.max_w_nmos_ * pmos_to_nmos_sizing_r; + C_driver_load = + 1024 * gate_C(load_nmos_width + load_pmos_width, 0, + is_dram); // TODO: this number 1024 needs to be revisited + R_wire_load = 3000 * l_ip.F_sz_um * g_tp.wire_outside_mat.R_per_um; - PredecBlk * predec_blk1 = new PredecBlk( - num_decoded_signals, - final_dec, - 0,//Assuming predec and dec are back to back - 0, - 1,//Each Predec only drives one final dec - false/*is_dram*/, - true); - PredecBlk * predec_blk2 = new PredecBlk( - num_decoded_signals, - final_dec, - 0,//Assuming predec and dec are back to back - 0, - 1,//Each Predec only drives one final dec - false/*is_dram*/, - false); + final_dec = new Decoder(num_decoded_signals, false, C_driver_load, + R_wire_load, false /*is_fa*/, false /*is_dram*/, + false /*wl_tr*/, // to use peri device + cell); - PredecBlkDrv * predec_blk_drv1 = new PredecBlkDrv(0, predec_blk1, false); - PredecBlkDrv * predec_blk_drv2 = new PredecBlkDrv(0, predec_blk2, false); + PredecBlk *predec_blk1 = + new PredecBlk(num_decoded_signals, final_dec, + 0, // Assuming predec and dec are back to back + 0, + 1, // Each Predec only drives one final dec + false /*is_dram*/, true); + PredecBlk *predec_blk2 = + new PredecBlk(num_decoded_signals, final_dec, + 0, // Assuming predec and dec are back to back + 0, + 1, // Each Predec only drives one final dec + false /*is_dram*/, false); - pre_dec = new Predec(predec_blk_drv1, predec_blk_drv2); + PredecBlkDrv *predec_blk_drv1 = new PredecBlkDrv(0, predec_blk1, false); + PredecBlkDrv *predec_blk_drv2 = new PredecBlkDrv(0, predec_blk2, false); - double area_decoder = final_dec->area.get_area() * num_decoded_signals * num_decoder_segments*num_decoders; - //double w_decoder = area_decoder / area.get_h(); - double area_pre_dec = (predec_blk_drv1->area.get_area() + - predec_blk_drv2->area.get_area() + - predec_blk1->area.get_area() + - predec_blk2->area.get_area())* - num_decoder_segments*num_decoders; - area.set_area(area.get_area()+ area_decoder + area_pre_dec); - double macro_layout_overhead = g_tp.macro_layout_overhead; - double chip_PR_overhead = g_tp.chip_layout_overhead; - area.set_area(area.get_area()*macro_layout_overhead*chip_PR_overhead); + pre_dec = new Predec(predec_blk_drv1, predec_blk_drv2); - inst_decoder_delay_power(); + double area_decoder = final_dec->area.get_area() * num_decoded_signals * + num_decoder_segments * num_decoders; + // double w_decoder = area_decoder / area.get_h(); + double area_pre_dec = + (predec_blk_drv1->area.get_area() + predec_blk_drv2->area.get_area() + + predec_blk1->area.get_area() + predec_blk2->area.get_area()) * + num_decoder_segments * num_decoders; + area.set_area(area.get_area() + area_decoder + area_pre_dec); + double macro_layout_overhead = g_tp.macro_layout_overhead; + double chip_PR_overhead = g_tp.chip_layout_overhead; + area.set_area(area.get_area() * macro_layout_overhead * chip_PR_overhead); - double sckRation = g_tp.sckt_co_eff; - power.readOp.dynamic *= sckRation; - power.writeOp.dynamic *= sckRation; - power.searchOp.dynamic *= sckRation; + inst_decoder_delay_power(); - double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty); - power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction; + double sckRation = g_tp.sckt_co_eff; + power.readOp.dynamic *= sckRation; + power.writeOp.dynamic *= sckRation; + power.searchOp.dynamic *= sckRation; + double long_channel_device_reduction = + longer_channel_device_reduction(device_ty, core_ty); + power.readOp.longer_channel_leakage = + power.readOp.leakage * long_channel_device_reduction; } -void inst_decoder::inst_decoder_delay_power() -{ - - double pppm_t[4] = {1,1,1,1}; - double squencer_passes = x86?2:1; +void inst_decoder::inst_decoder_delay_power() { + double pppm_t[4] = {1, 1, 1, 1}; + double squencer_passes = x86 ? 2 : 1; - set_pppm(pppm_t, squencer_passes*num_decoder_segments, num_decoder_segments, squencer_passes*num_decoder_segments, num_decoder_segments); - power = power + pre_dec->power*pppm_t; - set_pppm(pppm_t, squencer_passes*num_decoder_segments, num_decoder_segments*num_decoded_signals, - num_decoder_segments*num_decoded_signals, squencer_passes*num_decoder_segments); - power = power + final_dec->power*pppm_t; + set_pppm(pppm_t, squencer_passes * num_decoder_segments, num_decoder_segments, + squencer_passes * num_decoder_segments, num_decoder_segments); + power = power + pre_dec->power * pppm_t; + set_pppm(pppm_t, squencer_passes * num_decoder_segments, + num_decoder_segments * num_decoded_signals, + num_decoder_segments * num_decoded_signals, + squencer_passes * num_decoder_segments); + power = power + final_dec->power * pppm_t; } -void inst_decoder::leakage_feedback(double temperature) -{ - l_ip.temp = (unsigned int)round(temperature/10.0)*10; - uca_org_t init_result = init_interface(&l_ip); // init_result is dummy +void inst_decoder::leakage_feedback(double temperature) { + l_ip.temp = (unsigned int)round(temperature / 10.0) * 10; + uca_org_t init_result = init_interface(&l_ip); // init_result is dummy final_dec->leakage_feedback(temperature); pre_dec->leakage_feedback(temperature); - double pppm_t[4] = {1,1,1,1}; - double squencer_passes = x86?2:1; + double pppm_t[4] = {1, 1, 1, 1}; + double squencer_passes = x86 ? 2 : 1; - set_pppm(pppm_t, squencer_passes*num_decoder_segments, num_decoder_segments, squencer_passes*num_decoder_segments, num_decoder_segments); - power = pre_dec->power*pppm_t; + set_pppm(pppm_t, squencer_passes * num_decoder_segments, num_decoder_segments, + squencer_passes * num_decoder_segments, num_decoder_segments); + power = pre_dec->power * pppm_t; - set_pppm(pppm_t, squencer_passes*num_decoder_segments, num_decoder_segments*num_decoded_signals,num_decoder_segments*num_decoded_signals, squencer_passes*num_decoder_segments); - power = power + final_dec->power*pppm_t; + set_pppm(pppm_t, squencer_passes * num_decoder_segments, + num_decoder_segments * num_decoded_signals, + num_decoder_segments * num_decoded_signals, + squencer_passes * num_decoder_segments); + power = power + final_dec->power * pppm_t; double sckRation = g_tp.sckt_co_eff; @@ -1086,19 +1358,20 @@ void inst_decoder::leakage_feedback(double temperature) power.writeOp.dynamic *= sckRation; power.searchOp.dynamic *= sckRation; - double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty); - power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction; + double long_channel_device_reduction = + longer_channel_device_reduction(device_ty, core_ty); + power.readOp.longer_channel_leakage = + power.readOp.leakage * long_channel_device_reduction; } -inst_decoder::~inst_decoder() -{ - local_result.cleanup(); +inst_decoder::~inst_decoder() { + local_result.cleanup(); - delete final_dec; + delete final_dec; - delete pre_dec->blk1; - delete pre_dec->blk2; - delete pre_dec->drv1; - delete pre_dec->drv2; - delete pre_dec; + delete pre_dec->blk1; + delete pre_dec->blk2; + delete pre_dec->drv1; + delete pre_dec->drv2; + delete pre_dec; } |
